From 8dae58bc1514c93eecabf2fc6aa6c5e93c0f7998 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 3 Jan 2008 17:17:18 -0800 Subject: [PATCH] revoke caps, mark stale --- src/mds/Capability.h | 24 ++++++++++++------------ src/mds/Locker.cc | 18 ++++++++++++++++++ src/mds/Locker.h | 2 ++ src/mds/Server.cc | 20 ++++++++++---------- src/mds/SessionMap.h | 17 ++++++++++------- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/mds/Capability.h b/src/mds/Capability.h index 8df19e6a70b22..6cb7ef520c34c 100644 --- a/src/mds/Capability.h +++ b/src/mds/Capability.h @@ -64,6 +64,7 @@ private: capseq_t last_sent, last_recv; bool suppress; + bool stale; public: xlist::item session_caps_item; @@ -72,13 +73,14 @@ public: wanted_caps(want), last_sent(s), last_recv(s), - suppress(false), + suppress(false), stale(false), session_caps_item(this) { } Capability(CInode *i, Export& other) : inode(i), wanted_caps(other.wanted), last_sent(0), last_recv(0), + suppress(false), stale(false), session_caps_item(this) { // issued vs pending if (other.issued & ~other.pending) @@ -89,6 +91,9 @@ public: bool is_suppress() { return suppress; } void set_suppress(bool b) { suppress = b; } + bool is_stale() { return stale; } + void set_stale(bool b) { stale = b; } + CInode *get_inode() { return inode; } void set_inode(CInode *i) { inode = i; } void add_to_cap_list(xlist& ls) { @@ -151,19 +156,8 @@ public: // issue caps; return seq number. capseq_t issue(int c) { - //int was = pending(); - //no! if (c == was && last_sent) return -1; // repeat of previous? - ++last_sent; cap_history[last_sent] = c; - - /* no! - // not recalling, just adding? - if (c & ~was && - cap_history.count(last_sent-1)) { - cap_history.erase(last_sent-1); - } - */ return last_sent; } capseq_t get_last_seq() { return last_sent; } @@ -225,6 +219,12 @@ public: return r; } + void revoke() { + if (pending()) + issue(0); + confirm_receipt(last_sent, 0); + } + // serializers void _encode(bufferlist& bl) { bl.append((char*)&wanted_caps, sizeof(wanted_caps)); diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 860b1000ba12e..e4a8792008aef 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -558,6 +558,24 @@ bool Locker::issue_caps(CInode *in) return (nissued == 0); // true if no re-issued, no callbacks } +void Locker::revoke_stale_caps(Session *session) +{ + dout(10) << "revoke_stale_caps for client " << session->inst.name << dendl; + + for (xlist::iterator p = session->caps.begin(); !p.end(); ++p) { + Capability *cap = *p; + CInode *in = cap->get_inode(); + int issued = cap->issued(); + if (issued) { + dout(10) << " revoking " << cap_string(issued) << " on " << *in << dendl; + cap->revoke(); + file_eval(&in->filelock); + } else { + dout(10) << " nothing issued on " << *in << dendl; + } + cap->set_stale(true); + } +} class C_MDL_RequestInodeFileCaps : public Context { Locker *locker; diff --git a/src/mds/Locker.h b/src/mds/Locker.h index 2993f04c7cfd9..7fb2ec97039b5 100644 --- a/src/mds/Locker.h +++ b/src/mds/Locker.h @@ -25,6 +25,7 @@ using std::list; using std::set; class MDS; +class Session; class CDir; class CInode; class CDentry; @@ -180,6 +181,7 @@ protected: version_t issue_file_data_version(CInode *in); Capability* issue_new_caps(CInode *in, int mode, Session *session); bool issue_caps(CInode *in); + void revoke_stale_caps(Session *session); protected: void handle_client_file_caps(class MClientFileCaps *m); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index f31d41ceeb312..7f4494898af32 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -285,23 +285,23 @@ void Server::terminate_sessions() void Server::find_idle_sessions() { - dout(10) << "find_idle_sessions " << mds->sessionmap.session_list.size() << dendl; + dout(10) << "find_idle_sessions" << dendl; utime_t cutoff = g_clock.now(); cutoff -= g_conf.mds_cap_timeout; while (1) { - Session *oldest = mds->sessionmap.get_oldest_session(); - if (!oldest) break; - dout(20) << "oldest session is " << oldest->inst << dendl; - if (oldest->last_cap_renew >= cutoff) { - dout(20) << "oldest session is " << oldest->inst << " and sufficiently new (" - << oldest->last_cap_renew << ")" << dendl; + Session *session = mds->sessionmap.get_oldest_active_session(); + if (!session) break; + dout(20) << "laggiest session is " << session->inst << dendl; + if (session->last_cap_renew >= cutoff) { + dout(20) << "laggiest session is " << session->inst << " and sufficiently new (" + << session->last_cap_renew << ")" << dendl; break; } - dout(10) << " expiring caps for " << oldest << " " << oldest->inst << " last " << oldest->last_cap_renew << dendl; - // write me!!! - break; + dout(10) << "new stale session " << session->inst << " last " << session->last_cap_renew << dendl; + mds->sessionmap.mark_session_stale(session); + mds->locker->revoke_stale_caps(session); } } diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index 739ffbe1bd458..1dc6cd1ea63ae 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -49,6 +49,7 @@ public: bool is_opening() { return state == STATE_OPENING; } bool is_open() { return state == STATE_OPEN; } bool is_closing() { return state == STATE_CLOSING; } + bool is_stale() { return state == STATE_STALE; } // -- caps -- private: @@ -122,7 +123,8 @@ private: MDS *mds; hash_map session_map; public: - xlist session_list; + xlist active_sessions; + xlist stale_sessions; public: // i am lazy version_t version, projected, committing, committed; @@ -145,8 +147,6 @@ public: return session_map[i.name]; Session *s = session_map[i.name] = new Session; s->inst = i; - session_list.push_back(&s->session_list_item); - assert(session_list.back() == s); return s; } void remove_session(Session *s) { @@ -156,11 +156,14 @@ public: } void touch_session(Session *s) { s->last_cap_renew = g_clock.now(); - session_list.push_back(&s->session_list_item); + active_sessions.push_back(&s->session_list_item); } - Session *get_oldest_session() { - if (session_list.empty()) return 0; - return session_list.front(); + Session *get_oldest_active_session() { + if (active_sessions.empty()) return 0; + return active_sessions.front(); + } + void mark_session_stale(Session *s) { + stale_sessions.push_back(&s->session_list_item); } void get_client_set(set& s) { -- 2.39.5