From 6389d409846c1c7f01f46c325b08148e76eb3b74 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 2 Jul 2008 14:00:56 -0700 Subject: [PATCH] mds: attach snaprealm to CInode, encoding/decoding --- src/TODO | 1 + src/include/encoding.h | 27 +++++++++++++++++++++++++++ src/mds/CDir.cc | 7 ++++++- src/mds/CInode.cc | 39 ++++++++++++++++++++++++++++++++++++++- src/mds/CInode.h | 14 ++++++++++++++ src/mds/MDCache.cc | 2 ++ src/mds/snap.cc | 2 +- src/mds/snap.h | 24 ++++++++++++++++++++++-- 8 files changed, 111 insertions(+), 5 deletions(-) diff --git a/src/TODO b/src/TODO index 0f370a97f3706..c97f857ef13f0 100644 --- a/src/TODO +++ b/src/TODO @@ -222,6 +222,7 @@ todo /- snap lineage in MOSDOp - rados bits to do clone+write / - cloning + - fix cloning on unlinked file (where snaps=[], but head may have follows_snap attr) - figure out how to fix up rados logging - snap collections - garbage collection diff --git a/src/include/encoding.h b/src/include/encoding.h index 56a2f4c6366fc..30af269093fb8 100644 --- a/src/include/encoding.h +++ b/src/include/encoding.h @@ -322,6 +322,33 @@ inline void decode(std::map& m, bufferlist::iterator& p) } } +// multimap +template +inline void encode(const std::multimap& m, bufferlist& bl) +{ + __u32 n = m.size(); + encode(n, bl); + for (typename std::multimap::const_iterator p = m.begin(); p != m.end(); ++p) { + encode(p->first, bl); + encode(p->second, bl); + } +} +template +inline void decode(std::multimap& m, bufferlist::iterator& p) +{ + __u32 n; + decode(n, p); + m.clear(); + while (n--) { + T k; + decode(k, p); + typename std::multimap::iterator it; + U u; + it = m.insert(std::pair(k, u)); + decode(it->second, p); + } +} + // hash_map template inline void encode(const __gnu_cxx::hash_map& m, bufferlist& bl) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 02db72ddaa719..4bbe0994f9d25 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1048,6 +1048,9 @@ void CDir::_fetched(bufferlist &bl) map xattrs; ::decode(xattrs, p); + + bufferlist snapbl; + ::decode(snapbl, p); if (dn) { if (dn->get_inode() == 0) { @@ -1073,9 +1076,10 @@ void CDir::_fetched(bufferlist &bl) if (in->is_symlink()) in->symlink = symlink; - // dirfragtree in->dirfragtree.swap(fragtree); in->xattrs.swap(xattrs); + in->decode_snap(snapbl); + // add cache->add_inode( in ); @@ -1294,6 +1298,7 @@ void CDir::_commit(version_t want) ::encode(in->dirfragtree, bl); ::encode(in->xattrs, bl); + in->encode_snap(bl); } } assert(n == 0); diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index d12101bc4d733..e4f2e9d52de18 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -22,6 +22,8 @@ #include "MDCache.h" #include "AnchorTable.h" +#include "snap.h" + #include "LogSegment.h" #include "common/Clock.h" @@ -963,6 +965,39 @@ CInodeDiscover* CInode::replicate_to( int rep ) } +// SNAP + +void CInode::open_snaprealm() +{ + if (!snaprealm) + snaprealm = new SnapRealm(mdcache, this); +} +void CInode::close_snaprealm() +{ + if (snaprealm) { + delete snaprealm; + snaprealm = 0; + } +} + +void CInode::encode_snap(bufferlist &bl) +{ + bufferlist snapbl; + if (snaprealm) + ::encode(snaprealm, snapbl); + ::encode(snapbl, bl); +} + +void CInode::decode_snap(bufferlist& snapbl) +{ + if (snapbl.length()) { + open_snaprealm(); + bufferlist::iterator p = snapbl.begin(); + ::decode(*snaprealm, p); + } +} + + // IMPORT/EXPORT @@ -973,7 +1008,8 @@ void CInode::encode_export(bufferlist& bl) ::encode(symlink, bl); ::encode(dirfragtree, bl); ::encode(xattrs, bl); - + encode_snap(bl); + bool dirty = is_dirty(); ::encode(dirty, bl); @@ -1012,6 +1048,7 @@ void CInode::decode_import(bufferlist::iterator& p, ::decode(symlink, p); ::decode(dirfragtree, p); ::decode(xattrs, p); + decode_snap(p); bool dirty; ::decode(dirty, p); diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 528a282ad5dcd..ddc6384c79b7d 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -284,6 +284,7 @@ private: }; ~CInode() { close_dirfrags(); + close_snaprealm(); } @@ -385,6 +386,19 @@ public: void clear_dirty_scattered(int type); void finish_scatter_gather_update(int type); + + // -- snap -- + void open_snaprealm(); + void close_snaprealm(); + void encode_snap(bufferlist &bl); + void decode_snap(bufferlist::iterator& p) { + bufferlist snapbl; + ::decode(snapbl, p); + if (snapbl.length()) + decode_snap(snapbl); + } + void decode_snap(bufferlist &bl); + // -- caps -- (new) // client caps int count_nonstale_caps() { diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 208ffffe8fedf..11829abfa719c 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -221,6 +221,8 @@ CInode *MDCache::create_root_inode() root->inode_auth = pair(0, CDIR_AUTH_UNKNOWN); + root->open_snaprealm(); // empty snaprealm + add_inode( root ); return root; diff --git a/src/mds/snap.cc b/src/mds/snap.cc index 3479d20e62f21..dbe40b027a91f 100644 --- a/src/mds/snap.cc +++ b/src/mds/snap.cc @@ -23,7 +23,7 @@ #define dout(x) if (x < g_conf.debug_mds) *_dout << dbeginl << g_clock.now() \ << " mds" << mdcache->mds->get_nodeid() \ - << ".snaprealm(" << dirino << ") " + << ".snaprealm(" << inode->ino() << ") " bool SnapRealm::open_parents(MDRequest *mdr) { diff --git a/src/mds/snap.h b/src/mds/snap.h index 999e37b2154a0..abe3567d0f6d4 100644 --- a/src/mds/snap.h +++ b/src/mds/snap.h @@ -63,14 +63,33 @@ class MDRequest; struct snaplink_t { inodeno_t dirino; snapid_t first; + void encode(bufferlist& bl) const { + ::encode(dirino, bl); + ::encode(first, bl); + } + void decode(bufferlist::iterator& bl) { + ::decode(dirino, bl); + ::decode(first, bl); + } }; +WRITE_CLASS_ENCODER(snaplink_t) struct SnapRealm { // realm state - inodeno_t dirino; map snaps; multimap parents, children; // key is "last" (or NOSNAP) + void encode(bufferlist& bl) const { + ::encode(snaps, bl); + ::encode(parents, bl); + ::encode(children, bl); + } + void decode(bufferlist::iterator& p) { + ::decode(snaps, p); + ::decode(parents, p); + ::decode(children, p); + } + // in-memory state MDCache *mdcache; CInode *inode; @@ -82,11 +101,12 @@ struct SnapRealm { xlist inodes_with_caps; // for efficient realm splits map client_cap_groups; // to identify clients who need snap notifications - SnapRealm(inodeno_t i, MDCache *c, CInode *in) : dirino(i), mdcache(c), inode(in) {} + SnapRealm(MDCache *c, CInode *in) : mdcache(c), inode(in) {} bool open_parents(MDRequest *mdr); void get_snap_list(set& s); }; +WRITE_CLASS_ENCODER(SnapRealm) -- 2.39.5