From ac2e6960ac0d0494adfdff30438d225a7530262b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 19 Aug 2008 13:18:19 -0700 Subject: [PATCH] mds: send RELEASED, FLUSHEDSNAP cap messages when cap updates are safe --- src/include/ceph_fs.h | 6 +++++- src/mds/Locker.cc | 33 +++++++++++++++++++++++++-------- src/mds/Locker.h | 4 ++-- src/mds/MDS.cc | 10 +++++++--- src/mds/SessionMap.h | 3 +++ 5 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index b9803bcce0192..0ea0f88bdc71d 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -794,10 +794,12 @@ enum { CEPH_CAP_OP_TRUNC, /* mds->client trunc notify (invalidate size+mtime) */ CEPH_CAP_OP_EXPORT, /* mds has exported the cap */ CEPH_CAP_OP_IMPORT, /* mds has imported the cap from specified mds */ + CEPH_CAP_OP_RELEASED, /* mds->client close out cap */ + CEPH_CAP_OP_FLUSHEDSNAP, /* mds->client flushed snap */ CEPH_CAP_OP_ACK, /* client->mds ack (if prior grant was a recall) */ CEPH_CAP_OP_REQUEST, /* client->mds request (update wanted bits) */ CEPH_CAP_OP_FLUSHSNAP, /* client->mds flush snapped metadata */ - CEPH_CAP_OP_RELEASE, /* client->mds released cap entirely */ + CEPH_CAP_OP_RELEASE, /* client->mds request release cap */ }; inline static const char* ceph_cap_op_name(int op) { @@ -806,6 +808,8 @@ inline static const char* ceph_cap_op_name(int op) { case CEPH_CAP_OP_TRUNC: return "trunc"; case CEPH_CAP_OP_EXPORT: return "export"; case CEPH_CAP_OP_IMPORT: return "import"; + case CEPH_CAP_OP_RELEASED: return "released"; + case CEPH_CAP_OP_FLUSHEDSNAP: return "flushedsnap"; case CEPH_CAP_OP_ACK: return "ack"; case CEPH_CAP_OP_REQUEST: return "request"; case CEPH_CAP_OP_FLUSHSNAP: return "flushsnap"; diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index bb69f0301a82a..3263ae23143fc 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -472,16 +472,18 @@ struct C_Locker_FileUpdate_finish : public Context { CInode *in; Mutation *mut; bool share; - C_Locker_FileUpdate_finish(Locker *l, CInode *i, Mutation *m, bool e=false) : - locker(l), in(i), mut(m), share(e) { + int client; + MClientCaps *ack; + C_Locker_FileUpdate_finish(Locker *l, CInode *i, Mutation *m, bool e=false, int c=-1, MClientCaps *ac = 0) : + locker(l), in(i), mut(m), share(e), client(c), ack(ac) { in->get(CInode::PIN_PTRWAITER); } void finish(int r) { - locker->file_update_finish(in, mut, share); + locker->file_update_finish(in, mut, share, client, ack); } }; -void Locker::file_update_finish(CInode *in, Mutation *mut, bool share) +void Locker::file_update_finish(CInode *in, Mutation *mut, bool share, int client, MClientCaps *ack) { dout(10) << "file_update_finish on " << *in << dendl; in->pop_and_dirty_projected_inode(mut->ls); @@ -494,6 +496,9 @@ void Locker::file_update_finish(CInode *in, Mutation *mut, bool share) if (share && in->is_auth() && in->filelock.is_stable()) share_inode_max_size(in); + + if (ack) + mds->send_message_client(ack, client); } Capability* Locker::issue_new_caps(CInode *in, @@ -985,7 +990,10 @@ void Locker::handle_client_caps(MClientCaps *m) } else { dout(10) << " flushsnap NOT releasing live cap" << dendl; } - _do_cap_update(in, has|had, in->get_caps_wanted(), follows, m); + + MClientCaps *ack = new MClientCaps(CEPH_CAP_OP_FLUSHEDSNAP, in->inode, 0, 0, 0, 0, 0); + ack->set_snap_follows(follows); + _do_cap_update(in, has|had, in->get_caps_wanted(), follows, m, ack); } else { // for this and all subsequent versions of this inode, @@ -1000,6 +1008,8 @@ void Locker::handle_client_caps(MClientCaps *m) << ", has " << cap_string(has) << " on " << *in << dendl; + MClientCaps *ack = 0; + if (m->get_seq() < cap->get_last_open()) { /* client may be trying to release caps (i.e. inode closed, etc.) * by setting reducing wanted set. but it may also be opening the @@ -1015,13 +1025,14 @@ void Locker::handle_client_caps(MClientCaps *m) in->remove_client_cap(client); if (!in->is_auth()) request_inode_file_caps(in); + ack = new MClientCaps(CEPH_CAP_OP_RELEASED, in->inode, 0, 0, 0, 0, 0); } else if (wanted != cap->wanted()) { dout(10) << " wanted " << cap_string(cap->wanted()) << " -> " << cap_string(wanted) << dendl; cap->set_wanted(wanted); } - _do_cap_update(in, has|had, in->get_caps_wanted() | wanted, follows, m); + _do_cap_update(in, has|had, in->get_caps_wanted() | wanted, follows, m, ack); // done? if (in->last == CEPH_NOSNAP) @@ -1038,7 +1049,8 @@ void Locker::handle_client_caps(MClientCaps *m) } -void Locker::_do_cap_update(CInode *in, int had, int all_wanted, snapid_t follows, MClientCaps *m) +void Locker::_do_cap_update(CInode *in, int had, int all_wanted, snapid_t follows, MClientCaps *m, + MClientCaps *ack) { dout(10) << "_do_cap_update had " << cap_string(had) << " on " << *in << dendl; @@ -1142,7 +1154,12 @@ void Locker::_do_cap_update(CInode *in, int had, int all_wanted, snapid_t follow mdcache->predirty_journal_parents(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY, 0, follows); mdcache->journal_dirty_inode(mut, &le->metablob, in, follows); - mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut, change_max)); + mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut, change_max, + m->get_source().num(), ack)); + } else { + // no update, ack now. + if (ack) + mds->send_message_client(ack, m->get_source().num()); } // reevaluate, waiters diff --git a/src/mds/Locker.h b/src/mds/Locker.h index fb4173d6d2b0a..ce9c7aaf694d0 100644 --- a/src/mds/Locker.h +++ b/src/mds/Locker.h @@ -204,13 +204,13 @@ protected: protected: void handle_client_caps(class MClientCaps *m); - void _do_cap_update(CInode *in, int had, int wanted, snapid_t follows, MClientCaps *m); + void _do_cap_update(CInode *in, int had, int wanted, snapid_t follows, MClientCaps *m, MClientCaps *ack=0); void request_inode_file_caps(CInode *in); void handle_inode_file_caps(class MInodeFileCaps *m); - void file_update_finish(CInode *in, Mutation *mut, bool share); + void file_update_finish(CInode *in, Mutation *mut, bool share, int client, MClientCaps *ack); public: bool check_inode_max_size(CInode *in, bool forceupdate=false, __u64 newsize=0); private: diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index 910aa72453e0c..797b0e545f1ca 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -323,9 +323,13 @@ void MDS::forward_message_mds(Message *m, int mds) void MDS::send_message_client(Message *m, int client) { - version_t seq = sessionmap.inc_push_seq(client); - dout(10) << "send_message_client client" << client << " seq " << seq << " " << *m << dendl; - messenger->send_message(m, sessionmap.get_session(entity_name_t::CLIENT(client))->inst); + if (sessionmap.have_session(entity_name_t::CLIENT(client))) { + version_t seq = sessionmap.inc_push_seq(client); + dout(10) << "send_message_client client" << client << " seq " << seq << " " << *m << dendl; + messenger->send_message(m, sessionmap.get_session(entity_name_t::CLIENT(client))->inst); + } else { + dout(10) << "send_message_client no session for client" << client << " " << *m << dendl; + } } void MDS::send_message_client(Message *m, entity_inst_t clientinst) diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index 9637eb6b66154..b167eb73dd0d9 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -153,6 +153,9 @@ public: // sessions bool empty() { return session_map.empty(); } + bool have_session(entity_name_t w) { + return session_map.count(w); + } Session* get_session(entity_name_t w) { if (session_map.count(w)) return session_map[w]; -- 2.39.5