From: Yan, Zheng Date: Tue, 26 Nov 2013 01:49:21 +0000 (+0800) Subject: mds: send info of imported caps back to the exporter (export dir) X-Git-Tag: v0.75~93^2~14 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ff8b9ac35866423187162039da983a04dbeb44f7;p=ceph.git mds: send info of imported caps back to the exporter (export dir) Introduce a new class Capability::Import and use it to send information of imported caps back to the exporter. This is preparation for including counterpart's information in cap import/export message. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/Capability.cc b/src/mds/Capability.cc index f1394308d9b..6a68fd76e05 100644 --- a/src/mds/Capability.cc +++ b/src/mds/Capability.cc @@ -24,10 +24,12 @@ void Capability::Export::encode(bufferlist &bl) const { ENCODE_START(2, 2, bl); + ::encode(cap_id, bl); ::encode(wanted, bl); ::encode(issued, bl); ::encode(pending, bl); ::encode(client_follows, bl); + ::encode(seq, bl); ::encode(mseq, bl); ::encode(last_issue_stamp, bl); ENCODE_FINISH(bl); @@ -36,10 +38,12 @@ void Capability::Export::encode(bufferlist &bl) const void Capability::Export::decode(bufferlist::iterator &p) { DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, p); + ::decode(cap_id, p); ::decode(wanted, p); ::decode(issued, p); ::decode(pending, p); ::decode(client_follows, p); + ::decode(seq, p); ::decode(mseq, p); ::decode(last_issue_stamp, p); DECODE_FINISH(p); @@ -47,10 +51,12 @@ void Capability::Export::decode(bufferlist::iterator &p) void Capability::Export::dump(Formatter *f) const { + f->dump_unsigned("cap_id", cap_id); f->dump_unsigned("wanted", wanted); f->dump_unsigned("issued", issued); f->dump_unsigned("pending", pending); f->dump_unsigned("client_follows", client_follows); + f->dump_unsigned("seq", seq); f->dump_unsigned("migrate_seq", mseq); f->dump_stream("last_issue_stamp") << last_issue_stamp; } @@ -67,6 +73,30 @@ void Capability::Export::generate_test_instances(list& ls) ls.back()->last_issue_stamp = utime_t(6, 7); } +void Capability::Import::encode(bufferlist &bl) const +{ + ENCODE_START(1, 1, bl); + ::encode(cap_id, bl); + ::encode(issue_seq, bl); + ::encode(mseq, bl); + ENCODE_FINISH(bl); +} + +void Capability::Import::decode(bufferlist::iterator &bl) +{ + DECODE_START(1, bl); + ::decode(cap_id, bl); + ::decode(issue_seq, bl); + ::decode(mseq, bl); + DECODE_FINISH(bl); +} + +void Capability::Import::dump(Formatter *f) const +{ + f->dump_unsigned("cap_id", cap_id); + f->dump_unsigned("issue_seq", issue_seq); + f->dump_unsigned("migrate_seq", mseq); +} /* * Capability::revoke_info diff --git a/src/mds/Capability.h b/src/mds/Capability.h index dbd318618f3..6f98aec05de 100644 --- a/src/mds/Capability.h +++ b/src/mds/Capability.h @@ -78,20 +78,33 @@ public: } public: struct Export { + int64_t cap_id; int32_t wanted; int32_t issued; int32_t pending; snapid_t client_follows; + ceph_seq_t seq; ceph_seq_t mseq; utime_t last_issue_stamp; Export() {} - Export(int w, int i, int p, snapid_t cf, ceph_seq_t s, utime_t lis) : - wanted(w), issued(i), pending(p), client_follows(cf), mseq(s), last_issue_stamp(lis) {} + Export(int64_t id, int w, int i, int p, snapid_t cf, ceph_seq_t s, ceph_seq_t m, utime_t lis) : + cap_id(id), wanted(w), issued(i), pending(p), client_follows(cf), + seq(s), mseq(m), last_issue_stamp(lis) {} void encode(bufferlist &bl) const; void decode(bufferlist::iterator &p); void dump(Formatter *f) const; static void generate_test_instances(list& ls); }; + struct Import { + int64_t cap_id; + ceph_seq_t issue_seq; + ceph_seq_t mseq; + Import() {} + Import(int64_t i, ceph_seq_t s, ceph_seq_t m) : cap_id(i), issue_seq(s), mseq(m) {} + void encode(bufferlist &bl) const; + void decode(bufferlist::iterator &p); + void dump(Formatter *f) const; + }; private: CInode *inode; @@ -273,7 +286,7 @@ public: // -- exports -- Export make_export() { - return Export(_wanted, issued(), pending(), client_follows, mseq+1, last_issue_stamp); + return Export(cap_id, _wanted, issued(), pending(), client_follows, last_sent, mseq+1, last_issue_stamp); } void rejoin_import() { mseq++; } void merge(Export& other, bool auth_cap) { @@ -319,6 +332,7 @@ public: }; WRITE_CLASS_ENCODER(Capability::Export) +WRITE_CLASS_ENCODER(Capability::Import) WRITE_CLASS_ENCODER(Capability::revoke_info) WRITE_CLASS_ENCODER(Capability) diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index 8cbb07edf42..6fe4c785b38 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -1431,6 +1431,9 @@ void Migrator::handle_export_ack(MExportDirAck *m) assert(it->second.state == EXPORT_EXPORTING); assert(it->second.tid == m->get_tid()); + bufferlist::iterator bp = m->imported_caps.begin(); + ::decode(it->second.peer_imported, bp); + it->second.state = EXPORT_LOGGINGFINISH; assert (g_conf->mds_kill_export_at != 9); set bounds; @@ -2374,10 +2377,12 @@ void Migrator::import_logged_start(dirfrag_t df, CDir *dir, int from, // force open client sessions and finish cap import mds->server->finish_force_open_sessions(imported_client_map, sseqmap); + map > imported_caps; + for (map >::iterator p = it->second.peer_exports.begin(); p != it->second.peer_exports.end(); ++p) { - finish_import_inode_caps(p->first, true, p->second); + finish_import_inode_caps(p->first, true, p->second, imported_caps[p->first->ino()]); } // send notify's etc. @@ -2386,7 +2391,10 @@ void Migrator::import_logged_start(dirfrag_t df, CDir *dir, int from, // test surviving observer of a failed migration that did not complete //assert(dir->replica_map.size() < 2 || mds->whoami != 0); - mds->send_message_mds(new MExportDirAck(dir->dirfrag(), it->second.tid), from); + MExportDirAck *ack = new MExportDirAck(dir->dirfrag(), it->second.tid); + ::encode(imported_caps, ack->imported_caps); + + mds->send_message_mds(ack, from); assert (g_conf->mds_kill_import_at != 8); cache->show_subtrees(); @@ -2554,10 +2562,11 @@ void Migrator::decode_import_inode_caps(CInode *in, } void Migrator::finish_import_inode_caps(CInode *in, bool auth_cap, - map &cap_map) + map &export_map, + map &import_map) { - for (map::iterator it = cap_map.begin(); - it != cap_map.end(); + for (map::iterator it = export_map.begin(); + it != export_map.end(); ++it) { dout(10) << "finish_import_inode_caps for client." << it->first << " on " << *in << dendl; Session *session = mds->sessionmap.get_session(entity_name_t::CLIENT(it->first.v)); @@ -2567,8 +2576,13 @@ void Migrator::finish_import_inode_caps(CInode *in, bool auth_cap, if (!cap) { cap = in->add_client_cap(it->first, session); } - cap->merge(it->second, auth_cap); + Capability::Import& im = import_map[it->first]; + im.cap_id = cap->get_cap_id(); + im.mseq = auth_cap ? it->second.mseq : cap->get_mseq(); + im.issue_seq = cap->get_last_seq() + 1; + + cap->merge(it->second, auth_cap); mds->mdcache->do_cap_import(session, in, cap); } @@ -2846,8 +2860,10 @@ void Migrator::logged_import_caps(CInode *in, // force open client sessions and finish cap import mds->server->finish_force_open_sessions(client_map, sseqmap); + map imported_caps; + assert(peer_exports.count(in)); - finish_import_inode_caps(in, false, peer_exports[in]); + finish_import_inode_caps(in, false, peer_exports[in], imported_caps); mds->locker->eval(in, CEPH_CAP_LOCKS, true); mds->send_message_mds(new MExportCapsAck(in->ino()), from); diff --git a/src/mds/Migrator.h b/src/mds/Migrator.h index 82132ef60d1..10d54511388 100644 --- a/src/mds/Migrator.h +++ b/src/mds/Migrator.h @@ -88,6 +88,7 @@ protected: set locks; set warning_ack_waiting; set notify_ack_waiting; + map > peer_imported; list waiting_for_finish; }; @@ -299,7 +300,8 @@ public: bufferlist::iterator &blp, map >& cap_imports); void finish_import_inode_caps(CInode *in, bool auth_cap, - map &cap_map); + map &export_map, + map &import_map); int decode_import_dir(bufferlist::iterator& blp, int oldauth, CDir *import_root, diff --git a/src/mds/Server.cc b/src/mds/Server.cc index c9266a5dfa4..f746927ce98 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -6330,12 +6330,16 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen // srcdn inode import? if (!srcdn->is_auth() && destdn->is_auth()) { assert(mdr->more()->inode_import.length() > 0); + + map imported_caps; // finish cap imports finish_force_open_sessions(mdr->more()->imported_client_map, mdr->more()->sseq_map); if (mdr->more()->cap_imports.count(destdnl->get_inode())) { - mds->mdcache->migrator->finish_import_inode_caps(destdnl->get_inode(), srcdn->authority().first, - mdr->more()->cap_imports[destdnl->get_inode()]); + mds->mdcache->migrator->finish_import_inode_caps(destdnl->get_inode(), + mdr->more()->srcdn_auth_mds, + mdr->more()->cap_imports[destdnl->get_inode()], + imported_caps); } /* hack: add an auth pin for each xlock we hold. These were * remote xlocks previously but now they're local and diff --git a/src/messages/MExportDirAck.h b/src/messages/MExportDirAck.h index ae159610d0b..eb23789eedd 100644 --- a/src/messages/MExportDirAck.h +++ b/src/messages/MExportDirAck.h @@ -18,9 +18,10 @@ #include "MExportDir.h" class MExportDirAck : public Message { +public: dirfrag_t dirfrag; + bufferlist imported_caps; - public: dirfrag_t get_dirfrag() { return dirfrag; } MExportDirAck() : Message(MSG_MDS_EXPORTDIRACK) {} @@ -40,9 +41,11 @@ public: void decode_payload() { bufferlist::iterator p = payload.begin(); ::decode(dirfrag, p); + ::decode(imported_caps, p); } void encode_payload(uint64_t features) { ::encode(dirfrag, payload); + ::encode(imported_caps, payload); } };