]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: move dir purge and truncate into purgequeue
authorJohn Spray <john.spray@redhat.com>
Mon, 19 Dec 2016 14:03:04 +0000 (14:03 +0000)
committerJohn Spray <john.spray@redhat.com>
Wed, 8 Mar 2017 10:20:58 +0000 (10:20 +0000)
Signed-off-by: John Spray <john.spray@redhat.com>
src/mds/PurgeQueue.cc
src/mds/PurgeQueue.h
src/mds/StrayManager.cc
src/mds/StrayManager.h

index bcf1e99906534e19ca3802391115ac31eabc5c70..d39b09b2cc49077b0c16174c521a2e648b614bdf 100644 (file)
@@ -30,22 +30,26 @@ static ostream& _prefix(std::ostream *_dout, mds_rank_t rank) {
 void PurgeItem::encode(bufferlist &bl) const
 {
   ENCODE_START(1, 1, bl);
+  ::encode((uint8_t)action, bl);
   ::encode(ino, bl);
   ::encode(size, bl);
   ::encode(layout, bl, CEPH_FEATURE_FS_FILE_LAYOUT_V2);
   ::encode(old_pools, bl);
   ::encode(snapc, bl);
+  ::encode(fragtree, bl);
   ENCODE_FINISH(bl);
 }
 
 void PurgeItem::decode(bufferlist::iterator &p)
 {
   DECODE_START(1, p);
+  ::decode((uint8_t&)action, p);
   ::decode(ino, p);
   ::decode(size, p);
   ::decode(layout, p);
   ::decode(old_pools, p);
   ::decode(snapc, p);
+  ::decode(fragtree, p);
   DECODE_FINISH(p);
 }
 
@@ -131,6 +135,9 @@ void PurgeQueue::create(Context *fin)
   journaler.write_head(fin);
 }
 
+/**
+ * The `completion` context will always be called back via a Finisher
+ */
 void PurgeQueue::push(const PurgeItem &pi, Context *completion)
 {
   dout(4) << "pushing inode 0x" << std::hex << pi.ino << std::dec << dendl;
@@ -269,37 +276,72 @@ void PurgeQueue::_execute_item(
 
   in_flight[expire_to] = item;
 
-  // TODO: handle things other than normal file purges
-  // (directories, snapshot truncates)
+  SnapContext nullsnapc;
+
   C_GatherBuilder gather(cct);
-  if (item.size > 0) {
-    uint64_t num = Striper::get_num_objects(item.layout, item.size);
-    dout(10) << " 0~" << item.size << " objects 0~" << num
-             << " snapc " << item.snapc << " on " << item.ino << dendl;
-    filer.purge_range(item.ino, &item.layout, item.snapc,
-                      0, num, ceph::real_clock::now(), 0,
-                      gather.new_sub());
-  }
+  if (item.action == PurgeItem::PURGE_FILE) {
+    if (item.size > 0) {
+      uint64_t num = Striper::get_num_objects(item.layout, item.size);
+      dout(10) << " 0~" << item.size << " objects 0~" << num
+               << " snapc " << item.snapc << " on " << item.ino << dendl;
+      filer.purge_range(item.ino, &item.layout, item.snapc,
+                        0, num, ceph::real_clock::now(), 0,
+                        gather.new_sub());
+    }
 
-  // remove the backtrace object if it was not purged
-  object_t oid = CInode::get_object_name(item.ino, frag_t(), "");
-  if (!gather.has_subs() || !item.layout.pool_ns.empty()) {
-    object_locator_t oloc(item.layout.pool_id);
-    dout(10) << " remove backtrace object " << oid
-            << " pool " << oloc.pool << " snapc " << item.snapc << dendl;
-    objecter->remove(oid, oloc, item.snapc,
-                         ceph::real_clock::now(), 0,
-                         NULL, gather.new_sub());
-  }
+    // remove the backtrace object if it was not purged
+    object_t oid = CInode::get_object_name(item.ino, frag_t(), "");
+    if (!gather.has_subs() || !item.layout.pool_ns.empty()) {
+      object_locator_t oloc(item.layout.pool_id);
+      dout(10) << " remove backtrace object " << oid
+               << " pool " << oloc.pool << " snapc " << item.snapc << dendl;
+      objecter->remove(oid, oloc, item.snapc,
+                            ceph::real_clock::now(), 0,
+                            NULL, gather.new_sub());
+    }
 
-  // remove old backtrace objects
-  for (const auto &p : item.old_pools) {
-    object_locator_t oloc(p);
-    dout(10) << " remove backtrace object " << oid
-            << " old pool " << p << " snapc " << item.snapc << dendl;
-    objecter->remove(oid, oloc, item.snapc,
-                         ceph::real_clock::now(), 0,
-                         NULL, gather.new_sub());
+    // remove old backtrace objects
+    for (const auto &p : item.old_pools) {
+      object_locator_t oloc(p);
+      dout(10) << " remove backtrace object " << oid
+               << " old pool " << p << " snapc " << item.snapc << dendl;
+      objecter->remove(oid, oloc, item.snapc,
+                            ceph::real_clock::now(), 0,
+                            NULL, gather.new_sub());
+    }
+  } else if (item.action == PurgeItem::PURGE_DIR) {
+    object_locator_t oloc(metadata_pool);
+    std::list<frag_t> frags;
+    if (!item.fragtree.is_leaf(frag_t()))
+      item.fragtree.get_leaves(frags);
+    frags.push_back(frag_t());
+    for (const auto &frag : frags) {
+      object_t oid = CInode::get_object_name(item.ino, frag, "");
+      dout(10) << " remove dirfrag " << oid << dendl;
+      objecter->remove(oid, oloc, nullsnapc,
+                       ceph::real_clock::now(),
+                       0, NULL, gather.new_sub());
+    }
+  } else if (item.action == PurgeItem::TRUNCATE_FILE) {
+    const uint64_t num = Striper::get_num_objects(item.layout, item.size);
+    dout(10) << " 0~" << item.size << " objects 0~" << num
+            << " snapc " << item.snapc << " on " << item.ino << dendl;
+
+    // keep backtrace object
+    if (num > 1) {
+      filer.purge_range(item.ino, &item.layout, item.snapc,
+                       1, num - 1, ceph::real_clock::now(),
+                       0, gather.new_sub());
+    }
+    filer.zero(item.ino, &item.layout, item.snapc,
+              0, item.layout.object_size,
+              ceph::real_clock::now(),
+              0, true, NULL, gather.new_sub());
+  } else {
+    derr << "Invalid item (action=" << item.action << ") in purge queue, "
+            "dropping it" << dendl;
+    in_flight.erase(expire_to);
+    return;
   }
   assert(gather.has_subs());
 
index b7ed4345f732f5baf9a331ef9976a844e8797c7f..f6b4aa1569c3b88daaf508e4fbdd5f544e9e7bfd 100644 (file)
 class PurgeItem
 {
 public:
+  enum Action : uint8_t {
+    NONE = 0,
+    PURGE_FILE = 1,
+    TRUNCATE_FILE,
+    PURGE_DIR
+  };
+
+  Action action;
   inodeno_t ino;
   uint64_t size;
   file_layout_t layout;
   compact_set<int64_t> old_pools;
   SnapContext snapc;
+  fragtree_t fragtree;
 
   PurgeItem()
-   : ino(0), size(0)
+   : action(NONE), ino(0), size(0)
   {}
 
   void encode(bufferlist &bl) const;
index 0b793447633b2bc382e9e0970b5ff33f25e16d52..816f9249883cc84631f486dc5cd97716ba54c297 100644 (file)
@@ -15,8 +15,6 @@
 
 #include "common/perf_counters.h"
 
-#include "osdc/Objecter.h"
-#include "osdc/Filer.h"
 #include "mds/MDSRank.h"
 #include "mds/MDCache.h"
 #include "mds/MDLog.h"
@@ -99,65 +97,46 @@ void StrayManager::purge(CDentry *dn)
   // dir.  on recovery, we'll need to re-eval all strays anyway.
   
   SnapContext nullsnapc;
-  C_GatherBuilder gather(
-    g_ceph_context,
-    new C_OnFinisher(new C_IO_PurgeStrayPurged(
-        this, dn, false), mds->finisher));
 
+  PurgeItem item;
+  item.ino = in->inode.ino;
   if (in->is_dir()) {
-    object_locator_t oloc(mds->mdsmap->get_metadata_pool());
-    std::list<frag_t> ls;
-    if (!in->dirfragtree.is_leaf(frag_t()))
-      in->dirfragtree.get_leaves(ls);
-    ls.push_back(frag_t());
-    for (std::list<frag_t>::iterator p = ls.begin();
-         p != ls.end();
-         ++p) {
-      object_t oid = CInode::get_object_name(in->inode.ino, *p, "");
-      dout(10) << __func__ << " remove dirfrag " << oid << dendl;
-      mds->objecter->remove(oid, oloc, nullsnapc,
-                           ceph::real_clock::now(),
-                           0, gather.new_sub());
-    }
-    assert(gather.has_subs());
-    gather.activate();
-    return;
-  }
-
-  const SnapContext *snapc;
-  SnapRealm *realm = in->find_snaprealm();
-  if (realm) {
-    dout(10) << " realm " << *realm << dendl;
-    snapc = &realm->get_snap_context();
+    item.action = PurgeItem::PURGE_DIR;
+    item.fragtree = in->dirfragtree;
   } else {
-    dout(10) << " NO realm, using null context" << dendl;
-    snapc = &nullsnapc;
-    assert(in->last == CEPH_NOSNAP);
-  }
+    item.action = PurgeItem::PURGE_FILE;
 
-  uint64_t to = 0;
-  if (in->is_file()) {
-    to = in->inode.get_max_size();
-    to = MAX(in->inode.size, to);
-    // when truncating a file, the filer does not delete stripe objects that are
-    // truncated to zero. so we need to purge stripe objects up to the max size
-    // the file has ever been.
-    to = MAX(in->inode.max_size_ever, to);
-  }
+    const SnapContext *snapc;
+    SnapRealm *realm = in->find_snaprealm();
+    if (realm) {
+      dout(10) << " realm " << *realm << dendl;
+      snapc = &realm->get_snap_context();
+    } else {
+      dout(10) << " NO realm, using null context" << dendl;
+      snapc = &nullsnapc;
+      assert(in->last == CEPH_NOSNAP);
+    }
 
-  inode_t *pi = in->get_projected_inode();
+    uint64_t to = 0;
+    if (in->is_file()) {
+      to = in->inode.get_max_size();
+      to = MAX(in->inode.size, to);
+      // when truncating a file, the filer does not delete stripe objects that are
+      // truncated to zero. so we need to purge stripe objects up to the max size
+      // the file has ever been.
+      to = MAX(in->inode.max_size_ever, to);
+    }
 
-  PurgeItem item;
-  item.ino = in->inode.ino;
-  item.size = to;
-  item.layout = pi->layout;
-  item.old_pools = pi->old_pools;
-  item.snapc = *snapc;
+    inode_t *pi = in->get_projected_inode();
 
-  purge_queue.push(item, gather.new_sub());
+    item.size = to;
+    item.layout = pi->layout;
+    item.old_pools = pi->old_pools;
+    item.snapc = *snapc;
+  }
 
-  assert(gather.has_subs());
-  gather.activate();
+  purge_queue.push(item, new C_IO_PurgeStrayPurged(
+        this, dn, false));
 }
 
 class C_PurgeStrayLogged : public StrayManagerLogContext {
@@ -679,25 +658,20 @@ StrayManager::StrayManager(MDSRank *mds, PurgeQueue &purge_queue_)
   : delayed_eval_stray(member_offset(CDentry, item_stray)),
     mds(mds), logger(NULL), started(false), num_strays(0),
     num_strays_delayed(0), num_strays_enqueuing(0),
-    filer(mds->objecter, mds->finisher), purge_queue(purge_queue_)
+    purge_queue(purge_queue_)
 {
   assert(mds != NULL);
 }
 
 void StrayManager::truncate(CDentry *dn)
 {
-  CDentry::linkage_t *dnl = dn->get_projected_linkage();
-  CInode *in = dnl->get_inode();
+  const CDentry::linkage_t *dnl = dn->get_projected_linkage();
+  const CInode *in = dnl->get_inode();
   assert(in);
   dout(10) << __func__ << ": " << *dn << " " << *in << dendl;
   assert(!dn->is_replicated());
 
-  C_GatherBuilder gather(
-    g_ceph_context,
-    new C_OnFinisher(new C_IO_PurgeStrayPurged(this, dn, true),
-                    mds->finisher));
-
-  SnapRealm *realm = in->find_snaprealm();
+  const SnapRealm *realm = in->find_snaprealm();
   assert(realm);
   dout(10) << " realm " << *realm << dendl;
   const SnapContext *snapc = &realm->get_snap_context();
@@ -708,25 +682,17 @@ void StrayManager::truncate(CDentry *dn)
   // truncated to zero. so we need to purge stripe objects up to the max size
   // the file has ever been.
   to = MAX(in->inode.max_size_ever, to);
-  if (to > 0) {
-    uint64_t num = Striper::get_num_objects(in->inode.layout, to);
-    dout(10) << __func__ << " 0~" << to << " objects 0~" << num
-            << " snapc " << snapc << " on " << *in << dendl;
-
-    // keep backtrace object
-    if (num > 1) {
-      filer.purge_range(in->ino(), &in->inode.layout, *snapc,
-                       1, num - 1, ceph::real_clock::now(),
-                       0, gather.new_sub());
-    }
-    filer.zero(in->ino(), &in->inode.layout, *snapc,
-              0, in->inode.layout.object_size,
-              ceph::real_clock::now(),
-              0, true, gather.new_sub());
-  }
 
-  assert(gather.has_subs());
-  gather.activate();
+  assert(to > 0);
+
+  PurgeItem item;
+  item.ino = in->inode.ino;
+  item.layout = in->inode.layout;
+  item.snapc = *snapc;
+  item.size = to;
+
+  purge_queue.push(item, new C_IO_PurgeStrayPurged(
+        this, dn, true));
 }
 
 void StrayManager::_truncate_stray_logged(CDentry *dn, LogSegment *ls)
index 3124478bf63da145407c75e6aba264df7ef9d22c..eff21958ddfbbac2b127c4a0958086d832eb1853 100644 (file)
@@ -16,7 +16,6 @@
 
 #include "include/elist.h"
 #include <list>
-#include "osdc/Filer.h"
 #include "mds/PurgeQueue.h"
 
 class MDSRank;
@@ -49,8 +48,6 @@ class StrayManager
   // recorded by PurgeQueue yet
   uint64_t num_strays_enqueuing;
 
-  Filer filer;
-
   PurgeQueue &purge_queue;
 
   void truncate(CDentry *dn);