]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: save the oldest snapid of inode
authorYan, Zheng <zyan@redhat.com>
Tue, 20 Jan 2015 12:12:11 +0000 (20:12 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 5 Feb 2015 14:40:39 +0000 (22:40 +0800)
When moving a inode to different snapshot realm, we need to check if
the inode is snapshotted. If the inode is snapshotted, we create a
snapshot realm for it. The snapshot realm records inode's past snapshot
realm.

Currently there is no reliable way to check if a inode is snapshotted.
So add a new field to CInode the store the oldest snapid, it's used to
check if inode is snapshotted.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/CDir.cc
src/mds/CInode.cc
src/mds/CInode.h
src/mds/MDCache.cc
src/mds/Server.cc
src/mds/events/EMetaBlob.h
src/mds/journal.cc
src/mds/mdstypes.h

index 7c06d91154f6afa372eee2922e69b4abc42018fe..db6e5567955b478e9bd1cb3e2892ae7bf1584672 100644 (file)
@@ -1706,8 +1706,9 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
          
          in->dirfragtree.swap(inode_data.dirfragtree);
          in->xattrs.swap(inode_data.xattrs);
-         in->decode_snap_blob(inode_data.snap_blob);
          in->old_inodes.swap(inode_data.old_inodes);
+         in->decode_snap_blob(inode_data.snap_blob);
+         in->oldest_snap = inode_data.oldest_snap;
          if (snaps && !in->snaprealm)
            in->purge_stale_snap_data(*snaps);
 
index 1313a67c12d14efd2d41147c83494477de89eeb7..4f66ba60f7c0b9d4ab4c149f3d56d6e7705951d1 100644 (file)
@@ -1239,11 +1239,12 @@ void InodeStore::encode_bare(bufferlist &bl) const
   ::encode(xattrs, bl);
   ::encode(snap_blob, bl);
   ::encode(old_inodes, bl);
+  ::encode(oldest_snap, bl);
 }
 
 void InodeStore::encode(bufferlist &bl) const
 {
-  ENCODE_START(4, 4, bl);
+  ENCODE_START(5, 4, bl);
   encode_bare(bl);
   ENCODE_FINISH(bl);
 }
@@ -1272,12 +1273,14 @@ void InodeStore::decode_bare(bufferlist::iterator &bl, __u8 struct_v)
       ::decode(inode.layout, bl); // but we only care about the layout portion
     }
   }
+  if (struct_v >= 5)
+    ::decode(oldest_snap, bl);
 }
 
 
 void InodeStore::decode(bufferlist::iterator &bl)
 {
-  DECODE_START_LEGACY_COMPAT_LEN(4, 4, 4, bl);
+  DECODE_START_LEGACY_COMPAT_LEN(5, 4, 4, bl);
   decode_bare(bl, struct_v);
   DECODE_FINISH(bl);
 }
@@ -2375,7 +2378,7 @@ snapid_t CInode::get_oldest_snap()
   snapid_t t = first;
   if (!old_inodes.empty())
     t = old_inodes.begin()->second.first;
-  return MIN(t, first);
+  return MIN(t, oldest_snap);
 }
 
 old_inode_t& CInode::cow_old_inode(snapid_t follows, bool cow_head)
@@ -2389,6 +2392,9 @@ old_inode_t& CInode::cow_old_inode(snapid_t follows, bool cow_head)
   old.first = first;
   old.inode = *pi;
   old.xattrs = *px;
+
+  if (first < oldest_snap)
+    oldest_snap = first;
   
   dout(10) << " " << px->size() << " xattrs cowed, " << *px << dendl;
 
index e6d159230cdacf45dd57efa13cd862288afc96ac..bcb6da667c4790cf4ee7811965870a5f0964f0fe 100644 (file)
@@ -79,6 +79,9 @@ public:
   std::map<snapid_t, old_inode_t> old_inodes;   // key = last, value.first = first
   bufferlist                snap_blob;    // Encoded copy of SnapRealm, because we can't
                                            // rehydrate it without full MDCache
+  snapid_t                  oldest_snap;
+
+  InodeStore() : oldest_snap(CEPH_NOSNAP) { }
 
   /* Helpers */
   bool is_file() const    { return inode.is_file(); }
index 8696be773e6b01030911ab6a2dc5a8d278daafb6..67c8df7f9ca7bb77d4784916da0d7d4b55f1bce6 100644 (file)
@@ -1499,6 +1499,9 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last)
 
   oldin->inode.trim_client_ranges(last);
 
+  if (in->first < in->oldest_snap)
+    in->oldest_snap = in->first;
+
   in->first = last+1;
 
   dout(10) << "cow_inode " << *in << " to " << *oldin << dendl;
@@ -1563,7 +1566,7 @@ void MDCache::journal_cow_dentry(MutationImpl *mut, EMetaBlob *metablob,
     dnl = dn->get_projected_linkage();
   assert(!dnl->is_null());
 
-  if (dnl->is_primary()) {
+  if (dnl->is_primary() && dnl->get_inode()->is_multiversion()) {
     // multiversion inode.
     CInode *in = dnl->get_inode();
 
index 24cf29882a455fcb0baedc1299e8d769e19dae8f..eae6b6057d6e1000c31cd1dd7d78ec5b53356f07 100644 (file)
@@ -5205,7 +5205,7 @@ void Server::_unlink_local(MDRequestRef& mdr, CDentry *dn, CDentry *straydn)
     mdcache->predirty_journal_parents(mdr, &le->metablob, in, straydn->get_dir(), PREDIRTY_PRIMARY|PREDIRTY_DIR, 1);
 
     // project snaprealm, too
-    if (in->snaprealm || follows + 1 > dn->first)
+    if (in->snaprealm || follows + 1 > in->get_oldest_snap())
       in->project_past_snaprealm_parent(straydn->get_dir()->inode->find_snaprealm());
 
     pi->update_backtrace();
@@ -6406,7 +6406,7 @@ void Server::_rename_prepare(MDRequestRef& mdr,
     if (destdnl->is_primary()) {
       if (destdn->is_auth()) {
        // project snaprealm, too
-       if (oldin->snaprealm || dest_realm->get_newest_seq() + 1 > destdn->first)
+       if (oldin->snaprealm || dest_realm->get_newest_seq() + 1 > oldin->get_oldest_snap())
          oldin->project_past_snaprealm_parent(straydn->get_dir()->inode->find_snaprealm());
        straydn->first = MAX(oldin->first, next_dest_snap);
        metablob->add_primary_dentry(straydn, oldin, true, true);
@@ -6453,7 +6453,7 @@ void Server::_rename_prepare(MDRequestRef& mdr,
   } else if (srcdnl->is_primary()) {
     // project snap parent update?
     if (destdn->is_auth() && src_realm != dest_realm &&
-        (srci->snaprealm || src_realm->get_newest_seq() + 1 > srcdn->first))
+        (srci->snaprealm || src_realm->get_newest_seq() + 1 > srci->get_oldest_snap()))
       srci->project_past_snaprealm_parent(dest_realm);
     
     if (destdn->is_auth() && !destdnl->is_null())
index d8fd4588ee054ba71affc86da5d17440f013689e..60f64f859dbe44e4e09a876ed5edd8c230cbe244 100644 (file)
@@ -69,6 +69,7 @@ public:
     fragtree_t dirfragtree;
     map<string,bufferptr> xattrs;
     string symlink;
+    snapid_t oldest_snap;
     bufferlist snapbl;
     __u8 state;
     typedef map<snapid_t, old_inode_t> old_inodes_t;
@@ -80,9 +81,10 @@ public:
     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,
-           const bufferlist &sbl, __u8 st,
+           snapid_t os, const bufferlist &sbl, __u8 st,
            const old_inodes_t *oi = NULL) :
-      dn(d), dnfirst(df), dnlast(dl), dnv(v), inode(i), xattrs(xa), state(st)
+      dn(d), dnfirst(df), dnlast(dl), dnv(v), inode(i), xattrs(xa),
+      oldest_snap(os), state(st)
     {
       if (i.is_symlink())
        symlink = sym;
@@ -439,14 +441,14 @@ 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, snapbl,
-                                                         state,
-                                                         &in->old_inodes)));
+    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)));
   }
 
   // convenience: primary or remote?  figure it out.
@@ -501,9 +503,10 @@ private:
 
     string empty;
     roots.push_back(ceph::shared_ptr<fullbit>(new fullbit(empty, in->first, in->last, 0, *pi,
-                                                             *pdft, *px, in->symlink, snapbl,
-                                                             dirty ? fullbit::STATE_DIRTY : 0,
-                                                             &in->old_inodes)));
+                                                         *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) {
index ace30bd27e8cbe6885a196d1e1e48b4aedbe7018..025083fde0a250b79759ea5e74747e54ec55aab3 100644 (file)
@@ -397,7 +397,7 @@ void EMetaBlob::update_segment(LogSegment *ls)
 // EMetaBlob::fullbit
 
 void EMetaBlob::fullbit::encode(bufferlist& bl) const {
-  ENCODE_START(7, 5, bl);
+  ENCODE_START(8, 5, bl);
   ::encode(dn, bl);
   ::encode(dnfirst, bl);
   ::encode(dnlast, bl);
@@ -419,6 +419,7 @@ void EMetaBlob::fullbit::encode(bufferlist& bl) const {
   }
   if (!inode.is_dir())
     ::encode(snapbl, bl);
+  ::encode(oldest_snap, bl);
   ENCODE_FINISH(bl);
 }
 
@@ -464,6 +465,11 @@ void EMetaBlob::fullbit::decode(bufferlist::iterator &bl) {
     if (struct_v >= 7)
       ::decode(snapbl, bl);
   }
+  if (struct_v >= 8)
+    ::decode(oldest_snap, bl);
+  else
+    oldest_snap = CEPH_NOSNAP;
+
   DECODE_FINISH(bl);
 }
 
@@ -516,7 +522,7 @@ void EMetaBlob::fullbit::generate_test_instances(list<EMetaBlob::fullbit*>& ls)
   map<string,bufferptr> empty_xattrs;
   bufferlist empty_snapbl;
   fullbit *sample = new fullbit("/testdn", 0, 0, 0,
-                                inode, fragtree, empty_xattrs, "", empty_snapbl,
+                                inode, fragtree, empty_xattrs, "", 0, empty_snapbl,
                                 false, NULL);
   ls.push_back(sample);
 }
@@ -553,6 +559,7 @@ void EMetaBlob::fullbit::update_inode(MDS *mds, CInode *in)
    * be a no-op.. we have no children (namely open snaprealms) to
    * divy up
    */
+  in->oldest_snap = oldest_snap;
   in->decode_snap_blob(snapbl);
 }
 
index abe923c3003c8c4d41824200becd9294e3158dd4..95ebf496b229d75bdda5034b701ea3589d48cecf 100644 (file)
@@ -412,6 +412,8 @@ struct inode_t {
 
   version_t backtrace_version;
 
+  snapid_t oldest_snap;
+
   inode_t() : ino(0), rdev(0),
              mode(0), uid(0), gid(0), nlink(0),
              size(0), max_size_ever(0),