From: Yan, Zheng Date: Wed, 26 Jul 2017 02:07:17 +0000 (+0800) Subject: mds: properly update CInode::first and CDentry first X-Git-Tag: v13.0.2~852^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=df36378767bba651ae01b7459185eb914d3fc958;p=ceph.git mds: properly update CInode::first and CDentry first Signed-off-by: "Yan, Zheng" --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index f4a20105caf0..3aea894101c0 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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) { diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index b74a06faa626..a82485e0078f 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -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; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 340f719bed4a..9f7d50038e9e 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -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); diff --git a/src/mds/Server.h b/src/mds/Server.h index 2543953bab5f..3fb27f16e72f 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -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);