using namespace std;
+// variants to handle MMDSCacheRejoin::dn_strong version handling
+using StrongDentriesVariant = std::variant<
+ decltype(MMDSCacheRejoin::strong_dentries),
+ decltype(MMDSCacheRejoin::strong_dentries_new)
+>;
+
+using DnStrongVariant = std::variant<
+ MMDSCacheRejoin::dn_strong,
+ MMDSCacheRejoin::dn_strong_new
+>;
+
static ostream& _prefix(std::ostream *_dout, MDSRank *mds) {
return *_dout << "mds." << mds->get_nodeid() << ".cache ";
}
if (dn->is_replica(from)) {
if (ack) {
- const auto it = ack->strong_dentries.find(dir->dirfrag());
- if (it != ack->strong_dentries.end() && it->second.count(string_snap_t(dn->get_name(), dn->last)) > 0) {
- continue;
- }
+ //MMDSCacheRejoin::dn_strong version handling
+ if (!ack->strong_dentries_new.empty()) {
+ const auto it = ack->strong_dentries_new.find(dir->dirfrag());
+ if (it != ack->strong_dentries_new.end() && it->second.count(string_snap_t(dn->get_name(), dn->last)) > 0) {
+ continue;
+ }
+ } else {
+ const auto it = ack->strong_dentries.find(dir->dirfrag());
+ if (it != ack->strong_dentries.end() && it->second.count(string_snap_t(dn->get_name(), dn->last)) > 0) {
+ continue;
+ }
+ }
}
dentry_remove_replica(dn, from, gather_locks);
dout(10) << " rem " << *dn << dendl;
refragged = true;
}
- const auto it = strong->strong_dentries.find(dirfrag);
- if (it != strong->strong_dentries.end()) {
- const auto& dmap = it->second;
- for (const auto &q : dmap) {
- const string_snap_t& ss = q.first;
- const MMDSCacheRejoin::dn_strong& d = q.second;
- CDentry *dn;
- if (!refragged)
- dn = dir->lookup(ss.name, ss.snapid);
- else {
- frag_t fg = diri->pick_dirfrag(ss.name);
- dir = diri->get_dirfrag(fg);
- ceph_assert(dir);
- dn = dir->lookup(ss.name, ss.snapid);
- }
- if (!dn) {
- if (d.is_remote() || d.is_referent_remote()) {
- CInode *ref_in = nullptr;
- if (d.is_referent_remote()) {
- // TODO: ss.snapid for referent inode ? Since it's not snapped, always use
- // default CEPH_NOSNAP. Validate this by testing.
- ref_in = get_inode(d.referent_ino);
- if (!ref_in) {
- dout(20) << __func__ << " rejoin: no dentry, referent inode not found in memory inventing " << dendl;
- ref_in = rejoin_invent_inode(d.referent_ino, CEPH_NOSNAP);
- ref_in->set_remote_ino(d.remote_ino);
+ // MMDSCacheRejoin::dn_strong version handling
+ // When both of them are empty, strong_dentries is chosen but it doesn't matter since the map is empty
+ const StrongDentriesVariant sd_variant = (strong->strong_dentries_new.empty())
+ ? StrongDentriesVariant(strong->strong_dentries)
+ : StrongDentriesVariant(strong->strong_dentries_new);
+ std::visit([&](auto& strong_dentries) {
+ using Tp = std::decay_t<decltype(strong_dentries)>;
+ if constexpr (std::is_same_v<Tp, decltype(MMDSCacheRejoin::strong_dentries_new)>) {
+ dout(20) << " handle_cache_rejoin_strong" << " variant:strong_dentries_new " << dendl;
+ } else {
+ dout(20) << " handle_cache_rejoin_strong" << " variant:strong_dentries "
+ << "is_map_empty?" << (strong_dentries.empty()? "yes ":"no ") << dendl;
+ }
+ const auto it = strong_dentries.find(dirfrag);
+ if (it != strong_dentries.end()) {
+ const auto& dmap = it->second;
+ for (const auto &q : dmap) {
+ const string_snap_t& ss = q.first;
+ const DnStrongVariant dns_variant = q.second;
+ std::visit([&](auto& d) {
+ using T = std::decay_t<decltype(d)>;
+ CDentry *dn;
+ if (!refragged)
+ dn = dir->lookup(ss.name, ss.snapid);
+ else {
+ frag_t fg = diri->pick_dirfrag(ss.name);
+ dir = diri->get_dirfrag(fg);
+ ceph_assert(dir);
+ dn = dir->lookup(ss.name, ss.snapid);
+ }
+ if (!dn) {
+ if constexpr (std::is_same_v<T, MMDSCacheRejoin::dn_strong_new>) {
+ if (d.is_referent_remote()) {
+ CInode *ref_in = nullptr;
+ // ss.snapid for referent inode ? Since it's not snapped, always use CEPH_NOSNAP.
+ ref_in = get_inode(d.referent_ino);
+ if (!ref_in) {
+ dout(20) << "handle_cache_rejoin_strong " << " rejoin: no dentry, referent inode not found in memory inventing " << dendl;
+ ref_in = rejoin_invent_inode(d.referent_ino, CEPH_NOSNAP);
+ ref_in->set_remote_ino(d.remote_ino);
+ }
+ dout(20) << "handle_cache_rejoin_strong " << " rejoin: no dentry, add remote referent, referent inode= " << *ref_in << dendl;
+ dn = dir->add_remote_dentry(ss.name, ref_in, d.remote_ino, d.remote_d_type, mempool::mds_co::string(d.alternate_name), d.first, ss.snapid);
+ }
}
- dout(20) << __func__ << " rejoin: no dentry, referent inode invented " << *ref_in << dendl;
- } else {
- dout(20) << __func__ << " rejoin: no dentry, add remote inode " << dendl;
- }
- dn = dir->add_remote_dentry(ss.name, ref_in, d.remote_ino, d.remote_d_type, mempool::mds_co::string(d.alternate_name), d.first, ss.snapid);
- } else if (d.is_null()) {
- dn = dir->add_null_dentry(ss.name, d.first, ss.snapid);
- } else {
- CInode *in = get_inode(d.ino, ss.snapid);
- if (!in) in = rejoin_invent_inode(d.ino, ss.snapid);
- dn = dir->add_primary_dentry(ss.name, in, mempool::mds_co::string(d.alternate_name), d.first, ss.snapid);
- }
- dout(10) << " invented " << *dn << dendl;
- }
- CDentry::linkage_t *dnl = dn->get_linkage();
-
- // dn auth_pin?
- const auto pinned_it = strong->authpinned_dentries.find(dirfrag);
- if (pinned_it != strong->authpinned_dentries.end()) {
- const auto peer_reqid_it = pinned_it->second.find(ss);
- if (peer_reqid_it != pinned_it->second.end()) {
- for (const auto &r : peer_reqid_it->second) {
- dout(10) << " dn authpin by " << r << " on " << *dn << dendl;
-
- // get/create peer mdrequest
- MDRequestRef mdr;
- if (have_request(r.reqid))
- mdr = request_get(r.reqid);
- else
- mdr = request_start_peer(r.reqid, r.attempt, strong);
- mdr->auth_pin(dn);
+ if (d.is_remote()) {
+ dn = dir->add_remote_dentry(ss.name, nullptr, d.remote_ino, d.remote_d_type, mempool::mds_co::string(d.alternate_name), d.first, ss.snapid);
+ dout(20) << __func__ << " rejoin: no dentry, add remote inode " << dendl;
+ } else if (d.is_null()) {
+ dn = dir->add_null_dentry(ss.name, d.first, ss.snapid);
+ } else if (d.is_primary()) {
+ CInode *in = get_inode(d.ino, ss.snapid);
+ if (!in) in = rejoin_invent_inode(d.ino, ss.snapid);
+ dn = dir->add_primary_dentry(ss.name, in, mempool::mds_co::string(d.alternate_name), d.first, ss.snapid);
+ }
+ dout(10) << " invented " << *dn << dendl;
}
- }
- }
-
- // dn xlock?
- const auto xlocked_it = strong->xlocked_dentries.find(dirfrag);
- if (xlocked_it != strong->xlocked_dentries.end()) {
- const auto ss_req_it = xlocked_it->second.find(ss);
- if (ss_req_it != xlocked_it->second.end()) {
- const MMDSCacheRejoin::peer_reqid& r = ss_req_it->second;
- dout(10) << " dn xlock by " << r << " on " << *dn << dendl;
- MDRequestRef mdr = request_get(r.reqid); // should have this from auth_pin above.
- ceph_assert(mdr->is_auth_pinned(dn));
- if (!mdr->is_xlocked(&dn->versionlock)) {
- ceph_assert(dn->versionlock.can_xlock_local());
- dn->versionlock.get_xlock(mdr, mdr->get_client());
- mdr->emplace_lock(&dn->versionlock, MutationImpl::LockOp::XLOCK);
+ CDentry::linkage_t *dnl = dn->get_linkage();
+
+ // dn auth_pin?
+ const auto pinned_it = strong->authpinned_dentries.find(dirfrag);
+ if (pinned_it != strong->authpinned_dentries.end()) {
+ const auto peer_reqid_it = pinned_it->second.find(ss);
+ if (peer_reqid_it != pinned_it->second.end()) {
+ for (const auto &r : peer_reqid_it->second) {
+ dout(10) << " dn authpin by " << r << " on " << *dn << dendl;
+
+ // get/create peer mdrequest
+ MDRequestRef mdr;
+ if (have_request(r.reqid))
+ mdr = request_get(r.reqid);
+ else
+ mdr = request_start_peer(r.reqid, r.attempt, strong);
+ mdr->auth_pin(dn);
+ }
+ }
}
- if (dn->lock.is_stable())
- dn->auth_pin(&dn->lock);
- dn->lock.set_state(LOCK_XLOCK);
- dn->lock.get_xlock(mdr, mdr->get_client());
- mdr->emplace_lock(&dn->lock, MutationImpl::LockOp::XLOCK);
- }
- }
- dn->add_replica(from, d.nonce);
- dout(10) << " have " << *dn << dendl;
-
- if (dnl->is_primary()) {
- if (d.is_primary()) {
- if (vinodeno_t(d.ino, ss.snapid) != dnl->get_inode()->vino()) {
- // the survivor missed MDentryUnlink+MDentryLink messages ?
- ceph_assert(strong->strong_inodes.count(dnl->get_inode()->vino()) == 0);
- CInode *in = get_inode(d.ino, ss.snapid);
- ceph_assert(in);
- ceph_assert(in->get_parent_dn());
- rejoin_unlinked_inodes[from].insert(in);
- dout(7) << " sender has primary dentry but wrong inode" << dendl;
- }
- } else {
- // the survivor missed MDentryLink message ?
- ceph_assert(strong->strong_inodes.count(dnl->get_inode()->vino()) == 0);
- dout(7) << " sender doesn't have primay dentry" << dendl;
- }
- } else {
- if (d.is_primary()) {
- // the survivor missed MDentryUnlink message ?
- CInode *in = get_inode(d.ino, ss.snapid);
- ceph_assert(in);
- ceph_assert(in->get_parent_dn());
- rejoin_unlinked_inodes[from].insert(in);
- dout(7) << " sender has primary dentry but we don't" << dendl;
- }
+ // dn xlock?
+ const auto xlocked_it = strong->xlocked_dentries.find(dirfrag);
+ if (xlocked_it != strong->xlocked_dentries.end()) {
+ const auto ss_req_it = xlocked_it->second.find(ss);
+ if (ss_req_it != xlocked_it->second.end()) {
+ const MMDSCacheRejoin::peer_reqid& r = ss_req_it->second;
+ dout(10) << " dn xlock by " << r << " on " << *dn << dendl;
+ MDRequestRef mdr = request_get(r.reqid); // should have this from auth_pin above.
+ ceph_assert(mdr->is_auth_pinned(dn));
+ if (!mdr->is_xlocked(&dn->versionlock)) {
+ ceph_assert(dn->versionlock.can_xlock_local());
+ dn->versionlock.get_xlock(mdr, mdr->get_client());
+ mdr->emplace_lock(&dn->versionlock, MutationImpl::LockOp::XLOCK);
+ }
+ if (dn->lock.is_stable())
+ dn->auth_pin(&dn->lock);
+ dn->lock.set_state(LOCK_XLOCK);
+ dn->lock.get_xlock(mdr, mdr->get_client());
+ mdr->emplace_lock(&dn->lock, MutationImpl::LockOp::XLOCK);
+ }
+ }
+
+ dn->add_replica(from, d.nonce);
+ dout(10) << " have " << *dn << dendl;
+
+ if (dnl->is_primary()) {
+ if (d.is_primary()) {
+ if (vinodeno_t(d.ino, ss.snapid) != dnl->get_inode()->vino()) {
+ // the survivor missed MDentryUnlink+MDentryLink messages ?
+ ceph_assert(strong->strong_inodes.count(dnl->get_inode()->vino()) == 0);
+ CInode *in = get_inode(d.ino, ss.snapid);
+ ceph_assert(in);
+ ceph_assert(in->get_parent_dn());
+ rejoin_unlinked_inodes[from].insert(in);
+ dout(7) << " sender has primary dentry but wrong inode" << dendl;
+ }
+ } else {
+ // the survivor missed MDentryLink message ?
+ ceph_assert(strong->strong_inodes.count(dnl->get_inode()->vino()) == 0);
+ dout(7) << " sender doesn't have primay dentry" << dendl;
+ }
+ } else {
+ if (d.is_primary()) {
+ // the survivor missed MDentryUnlink message ?
+ CInode *in = get_inode(d.ino, ss.snapid);
+ ceph_assert(in);
+ ceph_assert(in->get_parent_dn());
+ rejoin_unlinked_inodes[from].insert(in);
+ dout(7) << " sender has primary dentry but we don't" << dendl;
+ }
+ }
+ }, dns_variant);
}
}
- }
+ }, sd_variant);
}
for (const auto &p : strong->strong_inodes) {
dout(10) << " got " << *dir << dendl;
// dentries
- auto it = ack->strong_dentries.find(p.first);
- if (it != ack->strong_dentries.end()) {
- for (const auto &q : it->second) {
- CDentry *dn = dir->lookup(q.first.name, q.first.snapid);
- if(!dn)
- dn = dir->add_null_dentry(q.first.name, q.second.first, q.first.snapid);
-
- CDentry::linkage_t *dnl = dn->get_linkage();
-
- ceph_assert(dn->last == q.first.snapid);
- if (dn->first != q.second.first) {
- dout(10) << " adjust dn.first " << dn->first << " -> " << q.second.first << " on " << *dn << dendl;
- dn->first = q.second.first;
- }
+ // MMDSCacheRejoin::dn_strong version handling
+ // When both of them are empty, strong_dentries is chosen but it doesn't matter since the map is empty
+ const StrongDentriesVariant sd_variant = (ack->strong_dentries_new.empty())
+ ? StrongDentriesVariant(ack->strong_dentries)
+ : StrongDentriesVariant(ack->strong_dentries_new);
+ std::visit([&](auto& strong_dentries) {
+ using Tp = std::decay_t<decltype(strong_dentries)>;
+ if constexpr (std::is_same_v<Tp, decltype(MMDSCacheRejoin::strong_dentries_new)>) {
+ dout(20) << " handle_cache_rejoin_ack" << " variant:strong_dentries_new " << dendl;
+ } else {
+ dout(20) << " handle_cache_rejoin_ack" << " variant:strong_dentries "
+ << "is_map_empty?" << (strong_dentries.empty()? "yes ":"no ") << dendl;
+ }
+ auto it = strong_dentries.find(p.first);
+ if (it != strong_dentries.end()) {
+ for (const auto &q : it->second) {
+ CDentry *dn = dir->lookup(q.first.name, q.first.snapid);
+ const DnStrongVariant dns_variant = q.second;
+ std::visit( [&](auto& d) {
+ using T = std::decay_t<decltype(d)>;
+ if(!dn)
+ dn = dir->add_null_dentry(q.first.name, q.second.first, q.first.snapid);
+
+ CDentry::linkage_t *dnl = dn->get_linkage();
+
+ ceph_assert(dn->last == q.first.snapid);
+ if (dn->first != q.second.first) {
+ dout(10) << " adjust dn.first " << dn->first << " -> " << q.second.first << " on " << *dn << dendl;
+ dn->first = q.second.first;
+ }
- // may have bad linkage if we missed dentry link/unlink messages
- if (dnl->is_primary()) {
- CInode *in = dnl->get_inode();
- if (!q.second.is_primary() ||
- vinodeno_t(q.second.ino, q.first.snapid) != in->vino()) {
- dout(10) << " had bad linkage for " << *dn << ", unlinking " << *in << dendl;
- dir->unlink_inode(dn);
- }
- } else if (dnl->is_remote()) {
- if (!q.second.is_remote() ||
- q.second.remote_ino != dnl->get_remote_ino() ||
- q.second.remote_d_type != dnl->get_remote_d_type()) {
- dout(10) << " had bad linkage for " << *dn << dendl;
- dir->unlink_inode(dn);
- }
- } else if (dnl->is_referent_remote()) {
- if (!q.second.is_referent_remote() ||
- q.second.remote_ino != dnl->get_remote_ino() ||
- q.second.remote_d_type != dnl->get_remote_d_type() ||
- q.second.referent_ino != dnl->get_referent_ino()) {
- dout(10) << __func__ << " had bad referent remote linkage for " << *dn << dendl;
- dir->unlink_inode(dn);
- }
- } else {
- if (!q.second.is_null())
- dout(10) << " had bad linkage for " << *dn << dendl;
- }
+ // may have bad linkage if we missed dentry link/unlink messages
+ if (dnl->is_primary()) {
+ CInode *in = dnl->get_inode();
+ if (!q.second.is_primary() ||
+ vinodeno_t(q.second.ino, q.first.snapid) != in->vino()) {
+ dout(10) << " had bad linkage for " << *dn << ", unlinking " << *in << dendl;
+ dir->unlink_inode(dn);
+ }
+ } else if (dnl->is_remote()) {
+ if (!q.second.is_remote() ||
+ q.second.remote_ino != dnl->get_remote_ino() ||
+ q.second.remote_d_type != dnl->get_remote_d_type()) {
+ dout(10) << " had bad linkage for " << *dn << dendl;
+ dir->unlink_inode(dn);
+ }
+ } else if (dnl->is_referent_remote()) {
+ if constexpr (std::is_same_v<T, MMDSCacheRejoin::dn_strong_new>) {
+ if (!d.is_referent_remote() ||
+ d.remote_ino != dnl->get_remote_ino() ||
+ d.remote_d_type != dnl->get_remote_d_type() ||
+ d.referent_ino != dnl->get_referent_ino()) {
+ dout(10) << " handle_cache_rejoin_ack" << " had bad referent remote linkage for " << *dn << dendl;
+ dir->unlink_inode(dn);
+ }
+ } else { //We shouldn't reach here
+ dout(10) << " handle_cache_rejoin_ack" << " dnl is referent remote but recevied dn_strong "
+ << "instead of dn_strong_new " << *dn << dendl;
+ // If reached, validate remote linkage
+ if (!q.second.is_remote() ||
+ q.second.remote_ino != dnl->get_remote_ino() ||
+ q.second.remote_d_type != dnl->get_remote_d_type()) {
+ dout(10) << " handle_cache_rejoin_ack" << " had bad linkage for " << *dn << dendl;
+ dir->unlink_inode(dn);
+ }
+ }
+ } else {
+ if (!q.second.is_null())
+ dout(10) << " had bad linkage for " << *dn << dendl;
+ }
- // hmm, did we have the proper linkage here?
- if (dnl->is_null() && !q.second.is_null()) {
- if (q.second.is_remote()) {
- dn->dir->link_remote_inode(dn, q.second.remote_ino, q.second.remote_d_type);
- } else if (q.second.is_referent_remote()) {
- CInode *ref_in = get_inode(q.second.referent_ino, CEPH_NOSNAP);
- if (!ref_in) {
- // barebones inode;
- ref_in = new CInode(this, false, 2, CEPH_NOSNAP);
- auto _inode = ref_in->_get_inode();
- _inode->ino = q.second.referent_ino;
- _inode->mode = S_IFREG;
- _inode->layout = default_file_layout;
- add_inode(ref_in);
- dout(10) << __func__ << " add inode " << *ref_in << dendl;
- } else if (ref_in->get_parent_dn()) {
- dout(10) << __func__ << " had bad referent linkage for " << *(ref_in->get_parent_dn())
- << ", unlinking referent inode" << *ref_in << dendl;
- ref_in->get_parent_dir()->unlink_inode(ref_in->get_parent_dn());
- }
- dn->dir->link_referent_inode(dn, ref_in, q.second.remote_ino, q.second.remote_d_type);
- isolated_inodes.erase(ref_in);
- } else {
- CInode *in = get_inode(q.second.ino, q.first.snapid);
- if (!in) {
- // barebones inode; assume it's dir, the full inode loop below will clean up.
- in = new CInode(this, false, q.second.first, q.first.snapid);
- auto _inode = in->_get_inode();
- _inode->ino = q.second.ino;
- _inode->mode = S_IFDIR;
- _inode->dir_layout.dl_dir_hash = g_conf()->mds_default_dir_hash;
- add_inode(in);
- dout(10) << " add inode " << *in << dendl;
- } else if (in->get_parent_dn()) {
- dout(10) << " had bad linkage for " << *(in->get_parent_dn())
- << ", unlinking " << *in << dendl;
- in->get_parent_dir()->unlink_inode(in->get_parent_dn());
+ // hmm, did we have the proper linkage here?
+ if (dnl->is_null() && !q.second.is_null()) {
+ if constexpr (std::is_same_v<T, MMDSCacheRejoin::dn_strong_new>) {
+ if (d.is_referent_remote()) {
+ CInode *ref_in = get_inode(d.referent_ino, CEPH_NOSNAP);
+ if (!ref_in) {
+ // barebones inode;
+ ref_in = new CInode(this, false, 2, CEPH_NOSNAP);
+ auto _inode = ref_in->_get_inode();
+ _inode->ino = d.referent_ino;
+ _inode->mode = S_IFREG;
+ _inode->layout = default_file_layout;
+ add_inode(ref_in);
+ dout(10) << " handle_cache_rejoin_ack" << " add referent inode " << *ref_in << dendl;
+ } else if (ref_in->get_parent_dn()) {
+ dout(10) << " handle_cache_rejoin_ack" << " had bad referent linkage for " << *(ref_in->get_parent_dn())
+ << ", unlinking referent inode" << *ref_in << dendl;
+ ref_in->get_parent_dir()->unlink_inode(ref_in->get_parent_dn());
+ }
+ dn->dir->link_referent_inode(dn, ref_in, d.remote_ino, d.remote_d_type);
+ isolated_inodes.erase(ref_in);
+ }
+ }
+ if (q.second.is_remote()) {
+ dn->dir->link_remote_inode(dn, q.second.remote_ino, q.second.remote_d_type);
+ } else if (q.second.is_primary()) {
+ CInode *in = get_inode(q.second.ino, q.first.snapid);
+ if (!in) {
+ // barebones inode; assume it's dir, the full inode loop below will clean up.
+ in = new CInode(this, false, q.second.first, q.first.snapid);
+ auto _inode = in->_get_inode();
+ _inode->ino = q.second.ino;
+ _inode->mode = S_IFDIR;
+ _inode->dir_layout.dl_dir_hash = g_conf()->mds_default_dir_hash;
+ add_inode(in);
+ dout(10) << " add inode " << *in << dendl;
+ } else if (in->get_parent_dn()) {
+ dout(10) << " had bad linkage for " << *(in->get_parent_dn())
+ << ", unlinking " << *in << dendl;
+ in->get_parent_dir()->unlink_inode(in->get_parent_dn());
+ }
+ dn->dir->link_primary_inode(dn, in);
+ isolated_inodes.erase(in);
+ }
}
- dn->dir->link_primary_inode(dn, in);
- isolated_inodes.erase(in);
- }
- }
- dn->set_replica_nonce(q.second.nonce);
- dn->lock.set_state_rejoin(q.second.lock, rejoin_waiters, survivor);
- dn->state_clear(CDentry::STATE_REJOINING);
- dout(10) << " got " << *dn << dendl;
+ dn->set_replica_nonce(q.second.nonce);
+ dn->lock.set_state_rejoin(q.second.lock, rejoin_waiters, survivor);
+ dn->state_clear(CDentry::STATE_REJOINING);
+ dout(10) << " got " << *dn << dendl;
+ }, dns_variant);
+ }
}
- }
+ }, sd_variant);
}
for (const auto& in : refragged_inodes) {
std::string alternate_name;
inodeno_t ino = 0;
inodeno_t remote_ino = 0;
- inodeno_t referent_ino = 0;
unsigned char remote_d_type = 0;
uint32_t nonce = 0;
int32_t lock = 0;
dn_strong() = default;
- dn_strong(snapid_t f, std::string_view altn, inodeno_t pi, inodeno_t ri, inodeno_t ref_ino, unsigned char rdt, int n, int l) :
- first(f), alternate_name(altn), ino(pi), remote_ino(ri), referent_ino(ref_ino), remote_d_type(rdt), nonce(n), lock(l) {}
+ dn_strong(snapid_t f, std::string_view altn, inodeno_t pi, inodeno_t ri, unsigned char rdt, int n, int l) :
+ first(f), alternate_name(altn), ino(pi), remote_ino(ri), remote_d_type(rdt), nonce(n), lock(l) {}
bool is_primary() const { return ino > 0; }
bool is_remote() const { return remote_ino > 0; }
- bool is_referent_remote() const { return remote_ino > 0 && referent_ino > 0; }
bool is_null() const { return ino == 0 && remote_ino == 0; }
void encode(ceph::buffer::list &bl) const {
using ceph::encode;
encode(nonce, bl);
encode(lock, bl);
encode(alternate_name, bl);
- encode(referent_ino, bl);
}
void decode(ceph::buffer::list::const_iterator &bl) {
using ceph::decode;
decode(nonce, bl);
decode(lock, bl);
decode(alternate_name, bl);
- decode(referent_ino, bl);
}
static void generate_test_instances(std::list<dn_strong*>& ls) {
ls.push_back(new dn_strong);
- ls.push_back(new dn_strong(1, "alternate_name", 2, 3, 4, 5, 6, 7));
+ ls.push_back(new dn_strong(1, "alternate_name", 2, 3, 4, 5, 6));
}
void dump(ceph::Formatter *f) const {
f->dump_unsigned("first", first);
f->dump_string("alternate_name", alternate_name);
f->dump_unsigned("ino", ino);
- f->dump_unsigned("referent_ino", referent_ino);
f->dump_unsigned("remote_ino", remote_ino);
f->dump_unsigned("remote_d_type", remote_d_type);
f->dump_unsigned("nonce", nonce);
};
WRITE_CLASS_ENCODER(dn_strong)
+ struct dn_strong_new {
+ snapid_t first;
+ std::string alternate_name;
+ inodeno_t ino = 0;
+ inodeno_t remote_ino = 0;
+ inodeno_t referent_ino = 0;
+ unsigned char remote_d_type = 0;
+ uint32_t nonce = 0;
+ int32_t lock = 0;
+ dn_strong_new() = default;
+ dn_strong_new(snapid_t f, std::string_view altn, inodeno_t pi, inodeno_t ri, inodeno_t ref_ino, unsigned char rdt, int n, int l) :
+ first(f), alternate_name(altn), ino(pi), remote_ino(ri), referent_ino(ref_ino), remote_d_type(rdt), nonce(n), lock(l) {}
+ bool is_primary() const { return ino > 0; }
+ bool is_remote() const { return remote_ino > 0 && referent_ino == 0; }
+ bool is_referent_remote() const { return remote_ino > 0 && referent_ino > 0; }
+ bool is_null() const { return ino == 0 && remote_ino == 0; }
+ void encode(ceph::buffer::list &bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(first, bl);
+ encode(ino, bl);
+ encode(remote_ino, bl);
+ encode(remote_d_type, bl);
+ encode(nonce, bl);
+ encode(lock, bl);
+ encode(alternate_name, bl);
+ encode(referent_ino, bl);
+ ENCODE_FINISH(bl);
+ }
+ void decode(ceph::buffer::list::const_iterator &bl) {
+ DECODE_START(1, bl);
+ decode(first, bl);
+ decode(ino, bl);
+ decode(remote_ino, bl);
+ decode(remote_d_type, bl);
+ decode(nonce, bl);
+ decode(lock, bl);
+ decode(alternate_name, bl);
+ decode(referent_ino, bl);
+ DECODE_FINISH(bl);
+ }
+ static void generate_test_instances(std::list<dn_strong_new*>& ls) {
+ ls.push_back(new dn_strong_new);
+ ls.push_back(new dn_strong_new(1, "alternate_name", 2, 3, 4, 5, 6, 7));
+ }
+ void dump(ceph::Formatter *f) const {
+ f->dump_unsigned("first", first);
+ f->dump_string("alternate_name", alternate_name);
+ f->dump_unsigned("ino", ino);
+ f->dump_unsigned("referent_ino", referent_ino);
+ f->dump_unsigned("remote_ino", remote_ino);
+ f->dump_unsigned("remote_d_type", remote_d_type);
+ f->dump_unsigned("nonce", nonce);
+ f->dump_unsigned("lock", lock);
+ }
+ };
+ WRITE_CLASS_ENCODER(dn_strong_new)
+
struct dn_weak {
snapid_t first;
inodeno_t ino = 0;
}
void add_strong_dentry(dirfrag_t df, std::string_view dname, std::string_view altn, snapid_t first, snapid_t last, inodeno_t pi, inodeno_t ri, inodeno_t ref_ino, unsigned char rdt, int n, int ls) {
auto& m = strong_dentries[df];
- m.insert_or_assign(string_snap_t(dname, last), dn_strong(first, altn, pi, ri, ref_ino, rdt, n, ls));
+ m.insert_or_assign(string_snap_t(dname, last), dn_strong(first, altn, pi, ri, rdt, n, ls));
+ auto& m1 = strong_dentries_new[df];
+ m1.insert_or_assign(string_snap_t(dname, last), dn_strong_new(first, altn, pi, ri, ref_ino, rdt, n, ls));
}
void add_dentry_authpin(dirfrag_t df, std::string_view dname, snapid_t last,
const metareqid_t& ri, __u32 attempt) {
encode(authpinned_dentries, payload);
encode(xlocked_dentries, payload);
encode(client_metadata_map, payload);
+ encode(strong_dentries_new, payload);
}
void decode_payload() override {
auto p = payload.cbegin();
decode(xlocked_dentries, p);
if (header.version >= 2)
decode(client_metadata_map, p);
+ if (header.version >= 3 )
+ decode(strong_dentries_new, p);
}
// -- data --
// strong
std::map<dirfrag_t, dirfrag_strong> strong_dirfrags;
std::map<dirfrag_t, std::map<string_snap_t, dn_strong> > strong_dentries;
+ std::map<dirfrag_t, std::map<string_snap_t, dn_strong_new> > strong_dentries_new;
std::map<vinodeno_t, inode_strong> strong_inodes;
// open
template<class T, typename... Args>
friend MURef<T> crimson::make_message(Args&&... args);
- static constexpr int HEAD_VERSION = 2;
+ static constexpr int HEAD_VERSION = 3;
static constexpr int COMPAT_VERSION = 1;
MMDSCacheRejoin(int o) : MMDSCacheRejoin() { op = o; }
WRITE_CLASS_ENCODER(MMDSCacheRejoin::dn_weak)
WRITE_CLASS_ENCODER(MMDSCacheRejoin::lock_bls)
WRITE_CLASS_ENCODER(MMDSCacheRejoin::peer_reqid)
+WRITE_CLASS_ENCODER(MMDSCacheRejoin::dn_strong_new)
inline std::ostream& operator<<(std::ostream& out, const MMDSCacheRejoin::peer_reqid& r) {
return out << r.reqid << '.' << r.attempt;