case MSG_MDS_EXPORTCAPS:
handle_export_caps(static_cast<MExportCaps*>(m));
break;
- case MSG_MDS_EXPORTCAPSACK:
- handle_export_caps_ack(static_cast<MExportCapsAck*>(m));
- break;
default:
assert(0);
in->encode_export(enc_state);
// caps
- encode_export_inode_caps(in, enc_state, exported_client_map);
+ encode_export_inode_caps(in, true, enc_state, exported_client_map);
}
-void Migrator::encode_export_inode_caps(CInode *in, bufferlist& bl,
+void Migrator::encode_export_inode_caps(CInode *in, bool auth_cap, bufferlist& bl,
map<client_t,entity_inst_t>& exported_client_map)
{
dout(20) << "encode_export_inode_caps " << *in << dendl;
map<client_t,Capability::Export> cap_map;
in->export_client_caps(cap_map);
::encode(cap_map, bl);
- ::encode(in->get_mds_caps_wanted(), bl);
+ if (auth_cap) {
+ ::encode(in->get_mds_caps_wanted(), bl);
- in->state_set(CInode::STATE_EXPORTINGCAPS);
- in->get(CInode::PIN_EXPORTINGCAPS);
+ in->state_set(CInode::STATE_EXPORTINGCAPS);
+ in->get(CInode::PIN_EXPORTINGCAPS);
+ }
// make note of clients named by exported capabilities
for (map<client_t, Capability*>::iterator it = in->client_caps.begin();
in->last_journaled = log_offset;
// caps
- decode_import_inode_caps(in, blp, peer_exports);
+ decode_import_inode_caps(in, true, blp, peer_exports);
// link before state -- or not! -sage
if (dn->get_linkage()->get_inode() != in) {
}
-void Migrator::decode_import_inode_caps(CInode *in,
+void Migrator::decode_import_inode_caps(CInode *in, bool auth_cap,
bufferlist::iterator &blp,
map<CInode*, map<client_t,Capability::Export> >& peer_exports)
{
map<client_t,Capability::Export> cap_map;
::decode(cap_map, blp);
- ::decode(in->get_mds_caps_wanted(), blp);
- if (!cap_map.empty() || !in->get_mds_caps_wanted().empty()) {
+ if (auth_cap)
+ ::decode(in->get_mds_caps_wanted(), blp);
+ if (!cap_map.empty() ||
+ (auth_cap && !in->get_mds_caps_wanted().empty())) {
peer_exports[in].swap(cap_map);
in->get(CInode::PIN_IMPORTINGCAPS);
}
cap->merge(it->second, auth_cap);
mds->mdcache->do_cap_import(session, in, cap, it->second.cap_id,
it->second.seq, it->second.mseq - 1, peer,
- auth_cap ? CEPH_CAP_FLAG_AUTH : 0);
+ auth_cap ? CEPH_CAP_FLAG_AUTH : CEPH_CAP_FLAG_RELEASE);
}
}
m->put();
}
-
-
-
-
-
-
-
/** cap exports **/
-
-
-
void Migrator::export_caps(CInode *in)
{
int dest = in->authority().first;
MExportCaps *ex = new MExportCaps;
ex->ino = in->ino();
- encode_export_inode_caps(in, ex->cap_bl, ex->client_map);
+ encode_export_inode_caps(in, false, ex->cap_bl, ex->client_map);
mds->send_message_mds(ex, dest);
}
-/* This function DOES put the passed message before returning*/
-void Migrator::handle_export_caps_ack(MExportCapsAck *ack)
-{
- CInode *in = cache->get_inode(ack->ino);
- assert(in);
- dout(10) << "handle_export_caps_ack " << *ack << " from " << ack->get_source()
- << " on " << *in
- << dendl;
-
- finish_export_inode_caps(in);
- ack->put();
-}
-
-
class C_M_LoggedImportCaps : public Context {
Migrator *migrator;
CInode *in;
// decode new caps
bufferlist::iterator blp = ex->cap_bl.begin();
- decode_import_inode_caps(in, blp, finish->peer_exports);
+ decode_import_inode_caps(in, false, blp, finish->peer_exports);
assert(!finish->peer_exports.empty()); // thus, inode is pinned.
// journal open client sessions
map<client_t,Capability::Import> imported_caps;
assert(peer_exports.count(in));
+ // clients will release caps from the exporter when they receive the cap import message.
finish_import_inode_caps(in, from, false, peer_exports[in], imported_caps);
mds->locker->eval(in, CEPH_CAP_LOCKS, true);
-
- mds->send_message_mds(new MExportCapsAck(in->ino()), from);
}
-
void encode_export_inode(CInode *in, bufferlist& bl,
map<client_t,entity_inst_t>& exported_client_map);
- void encode_export_inode_caps(CInode *in, bufferlist& bl,
+ void encode_export_inode_caps(CInode *in, bool auth_cap, bufferlist& bl,
map<client_t,entity_inst_t>& exported_client_map);
void finish_export_inode(CInode *in, utime_t now, int target,
map<client_t,Capability::Import>& peer_imported,
void export_unlock(CDir *dir);
void export_finish(CDir *dir);
- void handle_export_caps_ack(MExportCapsAck *m);
-
void export_freeze_finish(CDir *dir) {
utime_t start = export_freezing_state[dir].start_time;
export_freezing_dirs.erase(make_pair(start, dir));
LogSegment *ls, uint64_t log_offset,
map<CInode*, map<client_t,Capability::Export> >& cap_imports,
list<ScatterLock*>& updated_scatterlocks);
- void decode_import_inode_caps(CInode *in,
- bufferlist::iterator &blp,
+ void decode_import_inode_caps(CInode *in, bool auth_cap, bufferlist::iterator &blp,
map<CInode*, map<client_t,Capability::Export> >& cap_imports);
void finish_import_inode_caps(CInode *in, int from, bool auth_cap,
map<client_t,Capability::Export> &export_map,