]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: properly update CInode::first and CDentry first
authorYan, Zheng <zyan@redhat.com>
Wed, 26 Jul 2017 02:07:17 +0000 (10:07 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 5 Dec 2017 07:00:01 +0000 (15:00 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/CInode.cc
src/mds/MDCache.cc
src/mds/Server.cc
src/mds/Server.h

index f4a20105caf00933420f924a5025559f8609720f..3aea894101c084051f7038e0a8dea60368e73763 100644 (file)
@@ -1418,6 +1418,8 @@ void CInode::set_object_info(MDSCacheObjectInfo &info)
 void CInode::encode_lock_state(int type, bufferlist& bl)
 {
   ::encode(first, bl);
+  if (!is_base())
+    ::encode(parent->first, bl);
 
   switch (type) {
   case CEPH_LOCK_IAUTH:
@@ -1586,15 +1588,16 @@ void CInode::decode_lock_state(int type, bufferlist& bl)
 
   snapid_t newfirst;
   ::decode(newfirst, p);
-
   if (!is_auth() && newfirst != first) {
     dout(10) << "decode_lock_state first " << first << " -> " << newfirst << dendl;
-    assert(newfirst > first);
-    if (!is_multiversion() && parent) {
-      assert(parent->first == first);
+    first = newfirst;
+  }
+  if (!is_base()) {
+    ::decode(newfirst, p);
+    if (!parent->is_auth() && newfirst != parent->first) {
+      dout(10) << "decode_lock_state parent first " << first << " -> " << newfirst << dendl;
       parent->first = newfirst;
     }
-    first = newfirst;
   }
 
   switch (type) {
index b74a06faa626b894cf8dc6ce1339851addaae0d1..a82485e0078f649d48006b20cb65cb34364967fe 100644 (file)
@@ -1594,7 +1594,7 @@ void MDCache::journal_cow_dentry(MutationImpl *mut, EMetaBlob *metablob,
     if (in->get_projected_parent_dn() != dn) {
       assert(follows == CEPH_NOSNAP);
       realm = dn->dir->inode->find_snaprealm();
-      snapid_t dir_follows = realm->get_newest_snap();
+      snapid_t dir_follows = realm->get_newest_seq();
 
       if (dir_follows+1 > dn->first) {
        snapid_t oldfirst = dn->first;
index 340f719bed4a1f2226fd63ac12a7927deaec0109..9f7d50038e9e3130b620fb9386af5ac11e4a8e53 100644 (file)
@@ -2505,7 +2505,7 @@ CDentry* Server::prepare_null_dentry(MDRequestRef& mdr, CDir *dir, const string&
         respond_to_request(mdr, -EEXIST);
         return 0;
       }
-    } else {
+    } else if (!dir->inode->is_stray()) {
       dn->first = dir->inode->find_snaprealm()->get_newest_seq() + 1;
     }
 
@@ -4165,7 +4165,7 @@ void Server::do_open_truncate(MDRequestRef& mdr, int cmode)
   if (cmode & CEPH_FILE_MODE_WR) {
     pi->client_ranges[client].range.first = 0;
     pi->client_ranges[client].range.last = pi->get_layout_size_increment();
-    pi->client_ranges[client].follows = in->find_snaprealm()->get_newest_seq();
+    pi->client_ranges[client].follows = realm->get_newest_seq();
     changed_ranges = true;
   }
   
@@ -5877,6 +5877,11 @@ void Server::handle_client_unlink(MDRequestRef& mdr)
       return;
   }
 
+  SnapRealm *realm = in->find_snaprealm();
+  snapid_t follows = realm->get_newest_seq();
+  if (straydn)
+    straydn->first = MAX((uint64_t)in->first, follows + 1);
+
   // yay!
   if (in->is_dir() && in->has_subtree_root_dirfrag()) {
     // subtree root auths need to be witnesses
@@ -5904,7 +5909,7 @@ void Server::handle_client_unlink(MDRequestRef& mdr)
   if (dnl->is_remote() && !dnl->get_inode()->is_auth()) 
     _link_remote(mdr, false, dn, dnl->get_inode());
   else
-    _unlink_local(mdr, dn, straydn);
+    _unlink_local(mdr, dn, straydn, follows);
 }
 
 class C_MDS_unlink_local_finish : public ServerLogContext {
@@ -5921,15 +5926,13 @@ public:
   }
 };
 
-void Server::_unlink_local(MDRequestRef& mdr, CDentry *dn, CDentry *straydn)
+void Server::_unlink_local(MDRequestRef& mdr, CDentry *dn, CDentry *straydn, snapid_t follows)
 {
   dout(10) << "_unlink_local " << *dn << dendl;
 
   CDentry::linkage_t *dnl = dn->get_projected_linkage();
   CInode *in = dnl->get_inode();
 
-  SnapRealm *realm = in->find_snaprealm();
-  snapid_t follows = realm->get_newest_seq();
 
   // ok, let's do it.
   mdr->ls = mdlog->get_current_segment();
@@ -5948,7 +5951,6 @@ void Server::_unlink_local(MDRequestRef& mdr, CDentry *dn, CDentry *straydn)
   if (straydn) {
     assert(dnl->is_primary());
     straydn->push_projected_linkage(in);
-    straydn->first = follows + 1;
   }
 
   // the unlinked dentry
@@ -5993,6 +5995,11 @@ void Server::_unlink_local(MDRequestRef& mdr, CDentry *dn, CDentry *straydn)
 
   dn->push_projected_linkage();
 
+  if (straydn) {
+    assert(in->first <= straydn->first);
+    in->first = straydn->first;
+  }
+
   if (in->is_dir()) {
     assert(straydn);
     mdcache->project_subtree_rename(in, dn->get_dir(), straydn->get_dir());
@@ -7191,7 +7198,7 @@ void Server::_rename_prepare(MDRequestRef& mdr,
 
   SnapRealm *src_realm = srci->find_snaprealm();
   SnapRealm *dest_realm = destdn->get_dir()->inode->find_snaprealm();
-  snapid_t next_dest_snap = dest_realm->get_newest_seq() + 1;
+  snapid_t next_dest_snap = MAX(dest_realm->get_newest_seq(), src_realm->get_newest_seq()) + 1;
 
   // add it all to the metablob
   // target inode
@@ -7202,7 +7209,7 @@ void Server::_rename_prepare(MDRequestRef& mdr,
        // project snaprealm, too
        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);
+       straydn->first = MAX((uint64_t)oldin->first, dest_realm->get_newest_seq() + 1);
        metablob->add_primary_dentry(straydn, oldin, true, true);
       } else if (force_journal_stray) {
        dout(10) << " forced journaling straydn " << *straydn << dendl;
@@ -7226,7 +7233,7 @@ void Server::_rename_prepare(MDRequestRef& mdr,
       if (destdn->is_auth() && !destdnl->is_null())
        mdcache->journal_cow_dentry(mdr.get(), metablob, destdn, CEPH_NOSNAP, 0, destdnl);
       else
-       destdn->first = MAX(destdn->first, next_dest_snap);
+       destdn->first = next_dest_snap;
 
       if (destdn->is_auth())
         metablob->add_remote_dentry(destdn, true, srcdnl->get_remote_ino(), srcdnl->get_remote_d_type());
@@ -7239,6 +7246,7 @@ void Server::_rename_prepare(MDRequestRef& mdr,
       if (destdn->is_auth() && !destdnl->is_null())
        mdcache->journal_cow_dentry(mdr.get(), metablob, destdn, CEPH_NOSNAP, 0, destdnl);
       else
+       // FIXME: stray reintegration, do we need to update destdn->first?
        destdn->first = MAX(destdn->first, next_dest_snap);
 
       if (destdn->is_auth())
@@ -7252,8 +7260,8 @@ void Server::_rename_prepare(MDRequestRef& mdr,
     
     if (destdn->is_auth() && !destdnl->is_null())
       mdcache->journal_cow_dentry(mdr.get(), metablob, destdn, CEPH_NOSNAP, 0, destdnl);
-    else
-      destdn->first = MAX(destdn->first, next_dest_snap);
+
+    destdn->first = MAX(srci->first, next_dest_snap);
 
     if (destdn->is_auth())
       metablob->add_primary_dentry(destdn, srci, true, true);
@@ -7288,8 +7296,15 @@ void Server::_rename_prepare(MDRequestRef& mdr,
     dout(10) << " NOT journaling srcdn " << *srcdn << dendl;
 
   // make renamed inode first track the dn
-  if (srcdnl->is_primary() && destdn->is_auth())
-    srci->first = destdn->first;  
+  if (srcdnl->is_primary() && destdn->is_auth()) {
+    assert(srci->first <= destdn->first);
+    srci->first = destdn->first;
+  }
+  // make stray inode first track the straydn
+  if (straydn && straydn->is_auth()) {
+    assert(oldin->first <= straydn->first);
+    oldin->first = straydn->first;
+  }
 
   if (oldin && oldin->is_dir()) {
     assert(straydn);
index 2543953bab5fec2436641b2e0efbd78508c638dd..3fb27f16e72fa23d70b1a84e9f43b548300d66c9 100644 (file)
@@ -256,7 +256,7 @@ public:
   void handle_client_unlink(MDRequestRef& mdr);
   bool _dir_is_nonempty_unlocked(MDRequestRef& mdr, CInode *rmdiri);
   bool _dir_is_nonempty(MDRequestRef& mdr, CInode *rmdiri);
-  void _unlink_local(MDRequestRef& mdr, CDentry *dn, CDentry *straydn);
+  void _unlink_local(MDRequestRef& mdr, CDentry *dn, CDentry *straydn, snapid_t follows);
   void _unlink_local_finish(MDRequestRef& mdr,
                            CDentry *dn, CDentry *straydn,
                            version_t);