]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/mds/events/EMetaBlob.h
import 15.2.5
[ceph.git] / ceph / src / mds / events / EMetaBlob.h
index 28db4fc2b0e6ea3f85ce02f6398455a3f11cbd5f..52bcce20e19831bffd1a1d5d1172bc54b74dbe1e 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef CEPH_MDS_EMETABLOB_H
 #define CEPH_MDS_EMETABLOB_H
 
+#include <string_view>
+
 #include <stdlib.h>
 
 #include "../CInode.h"
@@ -37,7 +39,7 @@ struct MDSlaveUpdate;
  *
  * - make sure you adjust the inode.version for any modified inode you
  *   journal.  CDir and CDentry maintain a projected_version, but CInode
- *   doesn't, since the journaled inode usually has to be modifed 
+ *   doesn't, since the journaled inode usually has to be modified 
  *   manually anyway (to delay the change in the MDS's cache until after
  *   it is journaled).
  *
@@ -63,27 +65,24 @@ public:
     static const int STATE_DIRTYPARENT = (1<<1);
     static const int STATE_DIRTYPOOL   = (1<<2);
     static const int STATE_NEED_SNAPFLUSH = (1<<3);
-    typedef compact_map<snapid_t, old_inode_t> old_inodes_t;
-    string  dn;         // dentry
+    static const int STATE_EPHEMERAL_RANDOM = (1<<4);
+    std::string  dn;         // dentry
     snapid_t dnfirst, dnlast;
     version_t dnv{0};
-    inode_t inode;      // if it's not
+    CInode::mempool_inode inode;      // if it's not XXX should not be part of mempool; wait for std::pmr to simplify
     fragtree_t dirfragtree;
-    map<string,bufferptr> xattrs;
-    string symlink;
+    CInode::mempool_xattr_map xattrs;
+    std::string symlink;
     snapid_t oldest_snap;
     bufferlist snapbl;
     __u8 state{0};
-    old_inodes_t old_inodes;
-
-    fullbit(const fullbit& o);
-    const fullbit& operator=(const fullbit& o);
+    CInode::mempool_old_inode_map old_inodes; // XXX should not be part of mempool; wait for std::pmr to simplify
 
-    fullbit(const string& d, snapid_t df, snapid_t dl, 
-           version_t v, const inode_t& i, const fragtree_t &dft, 
-           const map<string,bufferptr> &xa, const string& sym,
+    fullbit(std::string_view d, snapid_t df, snapid_t dl, 
+           version_t v, const CInode::mempool_inode& i, const fragtree_t &dft,
+           const CInode::mempool_xattr_map &xa, std::string_view sym,
            snapid_t os, const bufferlist &sbl, __u8 st,
-           const old_inodes_t *oi = NULL) :
+           const CInode::mempool_old_inode_map *oi = NULL) :
       dn(d), dnfirst(df), dnlast(dl), dnv(v), inode(i), xattrs(xa),
       oldest_snap(os), state(st)
     {
@@ -95,22 +94,25 @@ public:
        old_inodes = *oi;
       snapbl = sbl;
     }
-    explicit fullbit(bufferlist::iterator &p) {
+    explicit fullbit(bufferlist::const_iterator &p) {
       decode(p);
     }
     fullbit() {}
+    fullbit(const fullbit&) = delete;
     ~fullbit() {}
+    fullbit& operator=(const fullbit&) = delete;
 
     void encode(bufferlist& bl, uint64_t features) const;
-    void decode(bufferlist::iterator &bl);
+    void decode(bufferlist::const_iterator &bl);
     void dump(Formatter *f) const;
-    static void generate_test_instances(list<EMetaBlob::fullbit*>& ls);
+    static void generate_test_instances(std::list<EMetaBlob::fullbit*>& ls);
 
     void update_inode(MDSRank *mds, CInode *in);
     bool is_dirty() const { return (state & STATE_DIRTY); }
     bool is_dirty_parent() const { return (state & STATE_DIRTYPARENT); }
     bool is_dirty_pool() const { return (state & STATE_DIRTYPOOL); }
     bool need_snapflush() const { return (state & STATE_NEED_SNAPFLUSH); }
+    bool is_export_ephemeral_random() const { return (state & STATE_EPHEMERAL_RANDOM); }
 
     void print(ostream& out) const {
       out << " fullbit dn " << dn << " [" << dnfirst << "," << dnlast << "] dnv " << dnv
@@ -137,28 +139,28 @@ public:
   /* remotebit - a dentry + remote inode link (i.e. just an ino)
    */
   struct remotebit {
-    string dn;
+    std::string dn;
     snapid_t dnfirst, dnlast;
     version_t dnv;
     inodeno_t ino;
     unsigned char d_type;
     bool dirty;
 
-    remotebit(const string& d, snapid_t df, snapid_t dl, version_t v, inodeno_t i, unsigned char dt, bool dr) : 
+    remotebit(std::string_view d, snapid_t df, snapid_t dl, version_t v, inodeno_t i, unsigned char dt, bool dr) : 
       dn(d), dnfirst(df), dnlast(dl), dnv(v), ino(i), d_type(dt), dirty(dr) { }
-    explicit remotebit(bufferlist::iterator &p) { decode(p); }
+    explicit remotebit(bufferlist::const_iterator &p) { decode(p); }
     remotebit(): dnfirst(0), dnlast(0), dnv(0), ino(0),
        d_type('\0'), dirty(false) {}
 
     void encode(bufferlist& bl) const;
-    void decode(bufferlist::iterator &bl);
+    void decode(bufferlist::const_iterator &bl);
     void print(ostream& out) const {
       out << " remotebit dn " << dn << " [" << dnfirst << "," << dnlast << "] dnv " << dnv
          << " ino " << ino
          << " dirty=" << dirty << std::endl;
     }
     void dump(Formatter *f) const;
-    static void generate_test_instances(list<remotebit*>& ls);
+    static void generate_test_instances(std::list<remotebit*>& ls);
   };
   WRITE_CLASS_ENCODER(remotebit)
 
@@ -166,21 +168,21 @@ public:
    * nullbit - a null dentry
    */
   struct nullbit {
-    string dn;
+    std::string dn;
     snapid_t dnfirst, dnlast;
     version_t dnv;
     bool dirty;
 
-    nullbit(const string& d, snapid_t df, snapid_t dl, version_t v, bool dr) : 
+    nullbit(std::string_view d, snapid_t df, snapid_t dl, version_t v, bool dr) :
       dn(d), dnfirst(df), dnlast(dl), dnv(v), dirty(dr) { }
-    explicit nullbit(bufferlist::iterator &p) { decode(p); }
+    explicit nullbit(bufferlist::const_iterator &p) { decode(p); }
     nullbit(): dnfirst(0), dnlast(0), dnv(0), dirty(false) {}
 
     void encode(bufferlist& bl) const;
-    void decode(bufferlist::iterator &bl);
+    void decode(bufferlist::const_iterator &bl);
     void dump(Formatter *f) const;
-    static void generate_test_instances(list<nullbit*>& ls);
-    void print(ostream& out) {
+    static void generate_test_instances(std::list<nullbit*>& ls);
+    void print(ostream& out) const {
       out << " nullbit dn " << dn << " [" << dnfirst << "," << dnlast << "] dnv " << dnv
          << " dirty=" << dirty << std::endl;
     }
@@ -206,12 +208,14 @@ public:
   private:
     mutable bufferlist dnbl;
     mutable bool dn_decoded;
-    mutable list<ceph::shared_ptr<fullbit> > dfull;
-    mutable list<remotebit> dremote;
-    mutable list<nullbit> dnull;
+    mutable list<fullbit> dfull;
+    mutable vector<remotebit> dremote;
+    mutable vector<nullbit> dnull;
 
   public:
     dirlump() : state(0), nfull(0), nremote(0), nnull(0), dn_decoded(true) { }
+    dirlump(const dirlump&) = delete;
+    dirlump& operator=(const dirlump&) = delete;
     
     bool is_complete() const { return state & STATE_COMPLETE; }
     void mark_complete() { state |= STATE_COMPLETE; }
@@ -224,26 +228,36 @@ public:
     bool is_dirty_dft() { return state & STATE_DIRTYDFT; }
     void mark_dirty_dft() { state |= STATE_DIRTYDFT; }
 
-    const list<ceph::shared_ptr<fullbit> > &get_dfull()   const { return dfull; }
-    const list<remotebit>                  &get_dremote() const { return dremote; }
-    const list<nullbit>                    &get_dnull()   const { return dnull; }
+    const list<fullbit>                        &get_dfull() const { return dfull; }
+    list<fullbit>                      &_get_dfull() { return dfull; }
+    const vector<remotebit>            &get_dremote() const { return dremote; }
+    const vector<nullbit>              &get_dnull() const { return dnull; }
 
-    void add_dnull(nullbit const &n)                   { dnull.push_back(n); };
-    void add_dfull(ceph::shared_ptr<fullbit> const &p) { dfull.push_back(p); };
-    void add_dremote(remotebit const &r)               { dremote.push_back(r); };
+    template< class... Args>
+    void add_dfull(Args&&... args) {
+      dfull.emplace_back(std::forward<Args>(args)...);
+    }
+    template< class... Args>
+    void add_dremote(Args&&... args) {
+      dremote.emplace_back(std::forward<Args>(args)...);
+    }
+    template< class... Args>
+    void add_dnull(Args&&... args) {
+      dnull.emplace_back(std::forward<Args>(args)...);
+    }
 
-    void print(dirfrag_t dirfrag, ostream& out) {
+    void print(dirfrag_t dirfrag, ostream& out) const {
       out << "dirlump " << dirfrag << " v " << fnode.version
          << " state " << state
          << " num " << nfull << "/" << nremote << "/" << nnull
          << std::endl;
       _decode_bits();
-      for (list<ceph::shared_ptr<fullbit> >::iterator p = dfull.begin(); p != dfull.end(); ++p)
-       (*p)->print(out);
-      for (list<remotebit>::iterator p = dremote.begin(); p != dremote.end(); ++p)
-       p->print(out);
-      for (list<nullbit>::iterator p = dnull.begin(); p != dnull.end(); ++p)
-       p->print(out);
+      for (const auto& p : dfull)
+       p.print(out);
+      for (const auto& p : dremote)
+       p.print(out);
+      for (const auto& p : dnull)
+       p.print(out);
     }
 
     string state_string() const {
@@ -265,38 +279,40 @@ public:
 
     // if this changes, update the versioning in encode for it!
     void _encode_bits(uint64_t features) const {
+      using ceph::encode;
       if (!dn_decoded) return;
-      ::encode(dfull, dnbl, features);
-      ::encode(dremote, dnbl);
-      ::encode(dnull, dnbl);
+      encode(dfull, dnbl, features);
+      encode(dremote, dnbl);
+      encode(dnull, dnbl);
     }
     void _decode_bits() const { 
+      using ceph::decode;
       if (dn_decoded) return;
-      bufferlist::iterator p = dnbl.begin();
-      ::decode(dfull, p);
-      ::decode(dremote, p);
-      ::decode(dnull, p);
+      auto p = dnbl.cbegin();
+      decode(dfull, p);
+      decode(dremote, p);
+      decode(dnull, p);
       dn_decoded = true;
     }
 
     void encode(bufferlist& bl, uint64_t features) const;
-    void decode(bufferlist::iterator &bl);
+    void decode(bufferlist::const_iterator &bl);
     void dump(Formatter *f) const;
-    static void generate_test_instances(list<dirlump*>& ls);
+    static void generate_test_instances(std::list<dirlump*>& ls);
   };
   WRITE_CLASS_ENCODER_FEATURES(dirlump)
 
   // my lumps.  preserve the order we added them in a list.
-  list<dirfrag_t>         lump_order;
+  vector<dirfrag_t>         lump_order;
   map<dirfrag_t, dirlump> lump_map;
-  list<ceph::shared_ptr<fullbit> > roots;
+  list<fullbit> roots;
 public:
-  list<pair<__u8,version_t> > table_tids;  // tableclient transactions
+  vector<pair<__u8,version_t> > table_tids;  // tableclient transactions
 
   inodeno_t opened_ino;
 public:
   inodeno_t renamed_dirino;
-  list<frag_t> renamed_dir_frags;
+  vector<frag_t> renamed_dir_frags;
 private:
   
   // ino (pre)allocation.  may involve both inotable AND session state.
@@ -307,27 +323,27 @@ private:
   entity_name_t client_name;          //            session
 
   // inodes i've truncated
-  list<inodeno_t> truncate_start;        // start truncate 
-  map<inodeno_t, log_segment_seq_t> truncate_finish;  // finished truncate (started in segment blah)
+  vector<inodeno_t> truncate_start;        // start truncate
+  map<inodeno_t, LogSegment::seq_t> truncate_finish;  // finished truncate (started in segment blah)
 
 public:
   vector<inodeno_t> destroyed_inodes;
 private:
 
   // idempotent op(s)
-  list<pair<metareqid_t,uint64_t> > client_reqs;
-  list<pair<metareqid_t,uint64_t> > client_flushes;
+  vector<pair<metareqid_t,uint64_t> > client_reqs;
+  vector<pair<metareqid_t,uint64_t> > client_flushes;
 
  public:
   void encode(bufferlist& bl, uint64_t features) const;
-  void decode(bufferlist::iterator& bl);
+  void decode(bufferlist::const_iterator& bl);
   void get_inodes(std::set<inodeno_t> &inodes) const;
   void get_paths(std::vector<std::string> &paths) const;
   void get_dentries(std::map<dirfrag_t, std::set<std::string> > &dentries) const;
   entity_name_t get_client_name() const {return client_name;}
 
   void dump(Formatter *f) const;
-  static void generate_test_instances(list<EMetaBlob*>& ls);
+  static void generate_test_instances(std::list<EMetaBlob*>& ls);
   // soft stateadd
   uint64_t last_subtree_map;
   uint64_t event_seq;
@@ -335,15 +351,17 @@ private:
   // for replay, in certain cases
   //LogSegment *_segment;
 
-  explicit EMetaBlob(MDLog *mdl = 0);  // defined in journal.cc
+  EMetaBlob() : opened_ino(0), renamed_dirino(0),
+                inotablev(0), sessionmapv(0), allocated_ino(0),
+                last_subtree_map(0), event_seq(0)
+                {}
+  EMetaBlob(const EMetaBlob&) = delete;
   ~EMetaBlob() { }
+  EMetaBlob& operator=(const EMetaBlob&) = delete;
 
   void print(ostream& out) {
-    for (list<dirfrag_t>::iterator p = lump_order.begin();
-        p != lump_order.end();
-        ++p) {
-      lump_map[*p].print(*p, out);
-    }
+    for (const auto &p : lump_order)
+      lump_map[p].print(p, out);
   }
 
   void add_client_req(metareqid_t r, uint64_t tid=0) {
@@ -358,7 +376,7 @@ private:
   }
 
   void add_opened_ino(inodeno_t ino) {
-    assert(!opened_ino);
+    ceph_assert(!opened_ino);
     opened_ino = ino;
   }
 
@@ -394,10 +412,8 @@ private:
   void add_null_dentry(dirlump& lump, CDentry *dn, bool dirty) {
     // add the dir
     lump.nnull++;
-    lump.add_dnull(nullbit(dn->get_name(), 
-                          dn->first, dn->last,
-                          dn->get_projected_version(), 
-                          dirty));
+    lump.add_dnull(dn->get_name(), dn->first, dn->last,
+                  dn->get_projected_version(), dirty);
   }
 
   void add_remote_dentry(CDentry *dn, bool dirty) {
@@ -413,11 +429,8 @@ private:
       rdt = dn->get_projected_linkage()->get_remote_d_type();
     }
     lump.nremote++;
-    lump.add_dremote(remotebit(dn->get_name(), 
-                              dn->first, dn->last,
-                               dn->get_projected_version(), 
-                               rino, rdt,
-                               dirty));
+    lump.add_dremote(dn->get_name(), dn->first, dn->last,
+                    dn->get_projected_version(), rino, rdt, dirty);
   }
 
   // return remote pointer to to-be-journaled inode
@@ -435,11 +448,15 @@ private:
     if (!in) 
       in = dn->get_projected_linkage()->get_inode();
 
+    if (in->is_ephemeral_rand()) {
+      state |= fullbit::STATE_EPHEMERAL_RANDOM;
+    }
+
     // make note of where this inode was last journaled
     in->last_journaled = event_seq;
     //cout << "journaling " << in->inode.ino << " at " << my_offset << std::endl;
 
-    const inode_t *pi = in->get_projected_inode();
+    const auto pi = in->get_projected_inode();
     if ((state & fullbit::STATE_DIRTY) && pi->is_backtrace_updated())
       state |= fullbit::STATE_DIRTYPARENT;
 
@@ -449,14 +466,9 @@ private:
       sr->encode(snapbl);
 
     lump.nfull++;
-    lump.add_dfull(ceph::shared_ptr<fullbit>(new fullbit(dn->get_name(),
-                                                        dn->first, dn->last,
-                                                        dn->get_projected_version(),
-                                                        *pi, in->dirfragtree,
-                                                        *in->get_projected_xattrs(),
-                                                        in->symlink,
-                                                        in->oldest_snap, snapbl,
-                                                        state, &in->old_inodes)));
+    lump.add_dfull(dn->get_name(), dn->first, dn->last, dn->get_projected_version(),
+                  *pi, in->dirfragtree, *in->get_projected_xattrs(), in->symlink,
+                  in->oldest_snap, snapbl, state, &in->old_inodes);
   }
 
   // convenience: primary or remote?  figure it out.
@@ -483,38 +495,34 @@ private:
       add_null_dentry(dn, dirty);
       return;
     }
-    assert(dn->get_projected_linkage()->is_primary());
+    ceph_assert(dn->get_projected_linkage()->is_primary());
     add_primary_dentry(dn, 0, dirty, dirty_parent, dirty_pool);
   }
 
-  void add_root(bool dirty, CInode *in, const inode_t *pi=0, fragtree_t *pdft=0, bufferlist *psnapbl=0,
-                   map<string,bufferptr> *px=0) {
+  void add_root(bool dirty, CInode *in) {
     in->last_journaled = event_seq;
     //cout << "journaling " << in->inode.ino << " at " << my_offset << std::endl;
 
-    if (!pi) pi = in->get_projected_inode();
-    if (!pdft) pdft = &in->dirfragtree;
-    if (!px) px = in->get_projected_xattrs();
+    const auto& pi = *(in->get_projected_inode());
+    const auto& pdft = in->dirfragtree;
+    const auto& px = *(in->get_projected_xattrs());
 
     bufferlist snapbl;
-    if (psnapbl)
-      snapbl = *psnapbl;
-    else
-      in->encode_snap_blob(snapbl);
+    const sr_t *sr = in->get_projected_srnode();
+    if (sr)
+      sr->encode(snapbl);
 
-    for (list<ceph::shared_ptr<fullbit> >::iterator p = roots.begin(); p != roots.end(); ++p) {
-      if ((*p)->inode.ino == in->ino()) {
+    for (auto p = roots.begin(); p != roots.end(); ++p) {
+      if (p->inode.ino == in->ino()) {
        roots.erase(p);
        break;
       }
     }
 
     string empty;
-    roots.push_back(ceph::shared_ptr<fullbit>(new fullbit(empty, in->first, in->last, 0, *pi,
-                                                         *pdft, *px, in->symlink,
-                                                         in->oldest_snap, snapbl,
-                                                         dirty ? fullbit::STATE_DIRTY : 0,
-                                                         &in->old_inodes)));
+    roots.emplace_back(empty, in->first, in->last, 0, pi, pdft, px, in->symlink,
+                      in->oldest_snap, snapbl, (dirty ? fullbit::STATE_DIRTY : 0),
+                      &in->old_inodes);
   }
   
   dirlump& add_dir(CDir *dir, bool dirty, bool complete=false) {