From: Greg Farnum Date: Fri, 26 Jun 2009 22:05:13 +0000 (-0700) Subject: uclient: Now handles STALE state nicely. X-Git-Tag: v0.10~119 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c7d9a5895897e534f55176b45fcdc52279fcb250;p=ceph.git uclient: Now handles STALE state nicely. --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 2ac2a31d21b2..bd231da743e1 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -900,12 +900,12 @@ void Client::handle_client_session(MClientSession *m) case CEPH_SESSION_RENEWCAPS: mds_sessions[from].cap_ttl = mds_sessions[from].last_cap_renew_request + mdsmap->get_session_timeout(); + wake_inode_waiters(from); break; case CEPH_SESSION_STALE: - // FIXME + mds_sessions[from].was_stale = true; break; - default: assert(0); } @@ -1170,8 +1170,7 @@ void Client::send_reconnect(int mds) dout(10) << " path " << path << dendl; in->caps[mds]->seq = 0; // reset seq. - m->add_cap(p->first.ino, in->caps[mds]->cap_id, - path.get_ino(), path.get_path(), + m->add_cap(p->first.ino, path.get_ino(), path.get_path(), // ino in->caps_wanted(), // wanted in->caps[mds]->issued, // issued in->inode.size, in->inode.mtime, in->inode.atime, in->snaprealm->ino); @@ -1644,6 +1643,15 @@ void Client::signal_cond_list(list& ls) ls.clear(); } +void Client::wake_inode_waiters(int mds_num) +{ + MDSSession * mds = &mds_sessions[mds_num]; + xlist::iterator iter = mds->caps.begin(); + while (!iter.end()){ + signal_cond_list((*iter)->inode->waitfor_caps); + ++iter; + } +} // flush dirty data (from objectcache) @@ -1721,6 +1729,10 @@ void Client::add_update_cap(Inode *in, int mds, __u64 cap_id, in->exporting_mseq = 0; } in->caps[mds] = cap = new InodeCap; + mds_sessions[mds].caps.push_back(&cap->cap_item); + cap->session = &mds_sessions[mds]; + cap->inode = in; + cap->gen = mds_sessions[mds].cap_gen; cap_list.push_back(&in->cap_item); } @@ -1763,6 +1775,8 @@ void Client::remove_cap(Inode *in, int mds) i.seq = cap->seq; i.migrate_seq = cap->mseq; session->release->caps.push_back(i); + + cap->cap_item.remove_myself(); if (in->auth_cap == cap) in->auth_cap = NULL; @@ -2501,19 +2515,25 @@ void Client::tick() void Client::renew_caps() { - dout(10) << "renew_caps" << dendl; + dout(10) << "renew_caps()" << dendl; last_cap_renew = g_clock.now(); for (map::iterator p = mds_sessions.begin(); p != mds_sessions.end(); p++) { dout(15) << "renew_caps requesting from mds" << p->first << dendl; - p->second.last_cap_renew_request = g_clock.now(); - messenger->send_message(new MClientSession(CEPH_SESSION_REQUEST_RENEWCAPS), - mdsmap->get_inst(p->first)); + renew_caps(p->first); } } +void Client::renew_caps(const int session) { + dout(10) << "renew_caps(session number)" << dendl; + mds_sessions[session].last_cap_renew_request = g_clock.now(); + messenger->send_message(new MClientSession(CEPH_SESSION_REQUEST_RENEWCAPS), + mdsmap->get_inst(session)); + +} + // =============================================================== // high level (POSIXy) interface diff --git a/src/client/Client.h b/src/client/Client.h index 42d6d21b1da7..93b269f80717 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -88,6 +88,23 @@ extern class Logger *client_logger; - when Dir is empty, it's removed (and it's Inode ref--) */ +struct InodeCap; +struct MDSSession { + version_t seq; + __u64 cap_gen; + utime_t cap_ttl, last_cap_renew_request; + int num_caps; + entity_inst_t inst; + bool closing; + bool was_stale; + + xlist caps; + + MClientCapRelease *release; + + MDSSession() : seq(0), cap_gen(0), num_caps(0), + closing(false), was_stale(false), release(NULL) {} +}; class Dir; class Inode; @@ -127,9 +144,6 @@ class Dir { bool is_empty() { return dentries.empty(); } }; - -struct InodeCap; - struct SnapRealm { inodeno_t ino; int nref; @@ -173,14 +187,20 @@ inline ostream& operator<<(ostream& out, const SnapRealm& r) { } struct InodeCap { + MDSSession *session; + Inode *inode; + xlist::item cap_item; + __u64 cap_id; unsigned issued; unsigned implemented; unsigned wanted; // as known to mds. __u64 seq; __u32 mseq; // migration seq + __u32 gen; - InodeCap() : issued(0), implemented(0), wanted(0), seq(0), mseq(0) {} + InodeCap() : session(NULL), inode(NULL), cap_item(this), issued(0), + implemented(0), wanted(0), seq(0), mseq(0), gen(0) {} }; struct CapSnap { @@ -335,12 +355,27 @@ class Inode { return caps.size() || exporting_mds >= 0; } + bool cap_is_valid(InodeCap* cap) { + cout << "cap_gen " << cap->session-> cap_gen << std::endl + << "session gen " << cap->gen << std::endl + << "cap expire " << cap->session->cap_ttl << std::endl + << "cur time " << g_clock.now() << std::endl; + if ((cap->session->cap_gen <= cap->gen) + && (g_clock.now() < cap->session->cap_ttl)) { + return true; + } + //if we make it here, the capabilities aren't up-to-date + cap->session->was_stale = true; + return true; + } + int caps_issued() { int c = exporting_issued | snap_caps; for (map::iterator it = caps.begin(); it != caps.end(); it++) - c |= it->second->issued; + if (cap_is_valid(it->second)) + c |= it->second->issued; return c; } @@ -559,6 +594,7 @@ class Client : public Dispatcher { Context *tick_event; utime_t last_cap_renew; void renew_caps(); + void renew_caps(int s); public: void tick(); @@ -572,18 +608,6 @@ public: bufferlist signed_ticket; // mds sessions - struct MDSSession { - version_t seq; - __u64 cap_gen; - utime_t cap_ttl, last_cap_renew_request; - int num_caps; - entity_inst_t inst; - bool closing; - - MClientCapRelease *release; - - MDSSession() : seq(0), cap_gen(0), num_caps(0), closing(false), release(NULL) {} - }; map mds_sessions; // mds -> push seq map > waiting_for_session; list waiting_for_mdsmap; @@ -698,6 +722,7 @@ protected: Mutex client_lock; // helpers + void wake_inode_waiters(int mds); void wait_on_list(list& ls); void signal_cond_list(list& ls);