]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: record completed cap flushes in session map
authorYan, Zheng <zyan@redhat.com>
Wed, 3 Jun 2015 10:52:08 +0000 (18:52 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 18 Aug 2015 08:49:50 +0000 (16:49 +0800)
This information is for detecting duplicated cap flushes when MDS
failovers. We only record completed cap flushes for clients whose
cap messages include TID of oldest cap flushes.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/Locker.cc
src/mds/SessionMap.h
src/mds/mdstypes.cc
src/mds/mdstypes.h

index 9d4bf2dbc5e996aaa56a857c61bd0298cf243e1a..7a4956381c2d39f6d14b59bc752c12b34bf732c6 100644 (file)
@@ -1715,8 +1715,18 @@ void Locker::file_update_finish(CInode *in, MutationRef& mut, bool share, client
 
   mut->apply();
   
-  if (ack)
-    mds->send_message_client_counted(ack, client);
+  if (ack) {
+    Session *session = mds->get_session(client);
+    if (session) {
+      // "oldest flush tid" > 0 means client uses unique TID for each flush
+      if (ack->get_oldest_flush_tid() > 0)
+       session->add_completed_flush(ack->get_client_tid());
+      mds->send_message_client_counted(ack, session);
+    } else {
+      dout(10) << " no session for client." << client << " " << *ack << dendl;
+      ack->put();
+    }
+  }
 
   set<CInode*> need_issue;
   drop_locks(mut.get(), &need_issue);
@@ -2456,6 +2466,13 @@ void Locker::handle_client_caps(MClientCaps *m)
     return;
   }
 
+  // "oldest flush tid" > 0 means client uses unique TID for each flush
+  if (m->get_oldest_flush_tid() > 0) {
+    if (session->trim_completed_flushes(m->get_oldest_flush_tid())) {
+      mds->mdlog->get_current_segment()->touched_sessions.insert(session->info.inst.name);
+    }
+  }
+
   CInode *head_in = mdcache->get_inode(m->get_ino());
   if (!head_in) {
     dout(7) << "handle_client_caps on unknown ino " << m->get_ino() << ", dropping" << dendl;
@@ -2526,6 +2543,7 @@ void Locker::handle_client_caps(MClientCaps *m)
       ack = new MClientCaps(CEPH_CAP_OP_FLUSHSNAP_ACK, in->ino(), 0, 0, 0, 0, 0, m->get_dirty(), 0, mds->get_osd_epoch_barrier());
       ack->set_snap_follows(follows);
       ack->set_client_tid(m->get_client_tid());
+      ack->set_oldest_flush_tid(m->get_oldest_flush_tid());
     }
 
     if (in == head_in ||
@@ -2601,6 +2619,7 @@ void Locker::handle_client_caps(MClientCaps *m)
       ack = new MClientCaps(CEPH_CAP_OP_FLUSH_ACK, in->ino(), 0, cap->get_cap_id(), m->get_seq(),
                            m->get_caps(), 0, m->get_dirty(), 0, mds->get_osd_epoch_barrier());
       ack->set_client_tid(m->get_client_tid());
+      ack->set_oldest_flush_tid(m->get_oldest_flush_tid());
     }
 
     // filter wanted based on what we could ever give out (given auth/replica status)
@@ -2877,6 +2896,11 @@ void Locker::_do_snap_update(CInode *in, snapid_t snap, int dirty, snapid_t foll
   mdcache->predirty_journal_parents(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY, 0, follows);
   mdcache->journal_dirty_inode(mut.get(), &le->metablob, in, follows);
 
+  // "oldest flush tid" > 0 means client uses unique TID for each flush
+  if (ack && ack->get_oldest_flush_tid() > 0)
+    le->metablob.add_client_flush(metareqid_t(m->get_source(), ack->get_client_tid()),
+                                 ack->get_oldest_flush_tid());
+
   mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut,
                                                                 false,
                                                                 client, NULL,
@@ -3122,6 +3146,11 @@ bool Locker::_do_cap_update(CInode *in, Capability *cap,
   mdcache->predirty_journal_parents(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY, 0, follows);
   mdcache->journal_dirty_inode(mut.get(), &le->metablob, in, follows);
 
+  // "oldest flush tid" > 0 means client uses unique TID for each flush
+  if (ack && ack->get_oldest_flush_tid() > 0)
+    le->metablob.add_client_flush(metareqid_t(m->get_source(), ack->get_client_tid()),
+                                 ack->get_oldest_flush_tid());
+
   mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut,
                                                                 change_max,
                                                                 client, cap,
index 93eb66095bee85548a2cf36af68ff1f7c2d47d7f..b73246e5baab34aaa937bf8cc61738a0c4453b82 100644 (file)
@@ -261,6 +261,25 @@ public:
     return true;
   }
 
+  void add_completed_flush(ceph_tid_t tid) {
+    info.completed_flushes.insert(tid);
+  }
+  bool trim_completed_flushes(ceph_tid_t mintid) {
+    bool erased_any = false;
+    while (!info.completed_flushes.empty() &&
+       (mintid == 0 || *info.completed_flushes.begin() < mintid)) {
+      info.completed_flushes.erase(info.completed_flushes.begin());
+      erased_any = true;
+    }
+    if (erased_any) {
+      completed_requests_dirty = true;
+    }
+    return erased_any;
+  }
+  bool have_completed_flush(ceph_tid_t tid) const {
+    return info.completed_flushes.count(tid);
+  }
+
   unsigned get_num_completed_requests() const { return info.completed_requests.size(); }
   unsigned get_num_trim_requests_warnings() { return num_trim_requests_warnings; }
   void inc_num_trim_requests_warnings() { ++num_trim_requests_warnings; }
index 28843a58a2879a1a3c35b8055549703994f05c2d..d0218ec8061264f34f01e0a1b99371d269e23412 100644 (file)
@@ -665,12 +665,13 @@ void old_rstat_t::generate_test_instances(list<old_rstat_t*>& ls)
  */
 void session_info_t::encode(bufferlist& bl) const
 {
-  ENCODE_START(4, 3, bl);
+  ENCODE_START(5, 3, bl);
   ::encode(inst, bl);
   ::encode(completed_requests, bl);
   ::encode(prealloc_inos, bl);   // hacky, see below.
   ::encode(used_inos, bl);
   ::encode(client_metadata, bl);
+  ::encode(completed_flushes, bl);
   ENCODE_FINISH(bl);
 }
 
@@ -695,6 +696,9 @@ void session_info_t::decode(bufferlist::iterator& p)
   if (struct_v >= 4) {
     ::decode(client_metadata, p);
   }
+  if (struct_v >= 5) {
+    ::decode(completed_flushes, p);
+  }
   DECODE_FINISH(p);
 }
 
index 9ed51e2499389c055f4a5b5c802d4322d4d1b26a..6fb5f12de4de5eb196ae23769c094d5804684b2c 100644 (file)
@@ -642,6 +642,7 @@ struct session_info_t {
   interval_set<inodeno_t> prealloc_inos;   // preallocated, ready to use.
   interval_set<inodeno_t> used_inos;       // journaling use
   std::map<std::string, std::string> client_metadata;
+  std::set<ceph_tid_t> completed_flushes;
 
   client_t get_client() const { return client_t(inst.name.num()); }
 
@@ -649,6 +650,7 @@ struct session_info_t {
     prealloc_inos.clear();
     used_inos.clear();
     completed_requests.clear();
+    completed_flushes.clear();
   }
 
   void encode(bufferlist& bl) const;