]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: find_ino_peer
authorSage Weil <sage.weil@dreamhost.com>
Thu, 31 Mar 2011 22:55:10 +0000 (15:55 -0700)
committerSage Weil <sage.weil@dreamhost.com>
Thu, 31 Mar 2011 23:07:10 +0000 (16:07 -0700)
Search for an ino on peer MDSs.  Still need to handle mds failure/recovery
handling.

Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
src/mds/MDCache.cc
src/mds/MDCache.h
src/messages/MMDSFindIno.h [new file with mode: 0644]
src/messages/MMDSFindInoReply.h [new file with mode: 0644]
src/msg/Message.cc
src/msg/Message.h

index fe6e3436d049dce1fea768a66a82f38aa84b2d65..dfe0f62d1a5e13a931d7c2b7c400f080f069f50d 100644 (file)
@@ -68,6 +68,9 @@
 #include "messages/MDentryLink.h"
 #include "messages/MDentryUnlink.h"
 
+#include "messages/MMDSFindIno.h"
+#include "messages/MMDSFindInoReply.h"
+
 #include "messages/MClientRequest.h"
 #include "messages/MClientCaps.h"
 #include "messages/MClientSnap.h"
@@ -136,6 +139,7 @@ MDCache::MDCache(MDS *m)
                         (0.9 *(g_conf.osd_max_write_size << 20));
 
   discover_last_tid = 0;
+  find_ino_peer_last_tid = 0;
 
   last_cap_id = 0;
 
@@ -6156,6 +6160,13 @@ void MDCache::dispatch(Message *m)
     break;
     
 
+  case MSG_MDS_FINDINO:
+    handle_find_ino((MMDSFindIno *)m);
+    break;
+  case MSG_MDS_FINDINOREPLY:
+    handle_find_ino_reply((MMDSFindInoReply *)m);
+    break;
+
     
   default:
     dout(7) << "cache unknown message " << m->get_type() << dendl;
@@ -6844,6 +6855,131 @@ void MDCache::make_trace(vector<CDentry*>& trace, CInode *in)
   trace.push_back(dn);
 }
 
+
+/* ---------------------------- */
+
+/*
+ * search for a given inode on MDS peers.  optionally start with the given node.
+
+
+ TODO 
+  - recover from mds node failure, recovery
+  - traverse path
+
+ */
+void MDCache::find_ino_peers(inodeno_t ino, Context *c, int hint)
+{
+  dout(5) << "find_ino_peers " << ino << " hint " << hint << dendl;
+  assert(!have_inode(ino));
+  
+  tid_t tid = ++find_ino_peer_last_tid;
+  find_ino_peer_info_t& fip = find_ino_peer[tid];
+  fip.ino = ino;
+  fip.tid = tid;
+  fip.fin = c;
+  fip.hint = hint;
+  _do_find_ino_peer(fip);
+}
+
+void MDCache::_do_find_ino_peer(find_ino_peer_info_t& fip)
+{
+  set<int> all, active;
+  mds->mdsmap->get_active_mds_set(active);
+  mds->mdsmap->get_mds_set(all);
+
+  dout(10) << "_do_find_ino_peer " << fip.tid << " " << fip.ino
+          << " active " << active << " all " << all
+          << " checked " << fip.checked
+          << dendl;
+    
+  int m = -1;
+  if (fip.hint >= 0) {
+    m = fip.hint;
+    fip.hint = -1;
+  } else {
+    for (set<int>::iterator p = active.begin(); p != active.end(); p++)
+      if (fip.checked.count(*p) == 0) {
+       m = *p;
+       break;
+      }
+  }
+  if (m < 0) {
+    if (all.size() > active.size()) {
+      dout(10) << "_do_find_ino_peer waiting for more peers to be active" << dendl;
+    } else {
+      dout(10) << "_do_find_ino_peer failed on " << fip.ino << dendl;
+      fip.fin->finish(-ESTALE);
+      delete fip.fin;
+      find_ino_peer.erase(fip.tid);
+    }
+  } else {
+    fip.checking = m;
+    mds->send_message_mds(new MMDSFindIno(fip.tid, fip.ino), m);
+  }
+}
+
+void MDCache::handle_find_ino(MMDSFindIno *m)
+{
+  dout(10) << "handle_find_ino " << *m << dendl;
+  MMDSFindInoReply *r = new MMDSFindInoReply(m->tid);
+  CInode *in = get_inode(m->ino);
+  if (in) {
+    in->make_path(r->path);
+    dout(10) << " have " << r->path << " " << *in << dendl;
+  }
+  mds->messenger->send_message(r, m->get_connection());
+  m->put();
+}
+
+
+void MDCache::handle_find_ino_reply(MMDSFindInoReply *m)
+{
+  map<tid_t, find_ino_peer_info_t>::iterator p = find_ino_peer.find(m->tid);
+  if (p != find_ino_peer.end()) {
+    dout(10) << "handle_find_ino_reply " << *m << dendl;
+    find_ino_peer_info_t& fip = p->second;
+
+    // success?
+    if (get_inode(fip.ino)) {
+      dout(10) << "handle_find_ino_reply successfully found " << fip.ino << dendl;
+      mds->queue_waiter(fip.fin);
+      find_ino_peer.erase(p);
+      m->put();
+      return;
+    }
+
+    int from = m->get_source().num();
+    if (fip.checking == from)
+      fip.checking = -1;
+    fip.checked.insert(from);
+
+    if (!m->path.empty()) {
+      // we got a path!
+      vector<CDentry*> trace;
+      int r = path_traverse(NULL, m, m->path, &trace, NULL, MDS_TRAVERSE_DISCOVER);
+      if (r > 0)
+       return; 
+      dout(0) << "handle_find_ino_reply failed with " << r << " on " << m->path 
+             << ", retrying" << dendl;
+      fip.checked.clear();
+      _do_find_ino_peer(fip);
+    } else {
+      // nope, continue.
+      _do_find_ino_peer(fip);
+    }      
+  } else {
+    dout(10) << "handle_find_ino_reply tid " << m->tid << " dne" << dendl;
+  }  
+  m->put();
+}
+
+
+
+
+
+
+/* ---------------------------- */
+
 /* This function takes over the reference to the passed Message */
 MDRequest *MDCache::request_start(MClientRequest *req)
 {
index 2c198bc2ec2b713eafb7e8c701bf89a0524d70de..f7d2fa7c01c22ce4fa54267a33733a1e13168c8d 100644 (file)
@@ -51,6 +51,8 @@ class MDirUpdate;
 class MDentryLink;
 class MDentryUnlink;
 class MLock;
+class MMDSFindIno;
+class MMDSFindInoReply;
 
 class Message;
 class MClientRequest;
@@ -1011,6 +1013,25 @@ public:
 
   void make_trace(vector<CDentry*>& trace, CInode *in);
   
+  struct find_ino_peer_info_t {
+    inodeno_t ino;
+    tid_t tid;
+    Context *fin;
+    int hint;
+    int checking;
+    set<int> checked;
+
+    find_ino_peer_info_t() : tid(0), fin(NULL), hint(-1), checking(-1) {}
+  };
+
+  map<tid_t, find_ino_peer_info_t> find_ino_peer;
+  tid_t find_ino_peer_last_tid;
+
+  void find_ino_peers(inodeno_t ino, Context *c, int hint=-1);
+  void _do_find_ino_peer(find_ino_peer_info_t& fip);
+  void handle_find_ino(MMDSFindIno *m);
+  void handle_find_ino_reply(MMDSFindInoReply *m);
+
   // -- anchors --
 public:
   void anchor_create_prep_locks(MDRequest *mdr, CInode *in, set<SimpleLock*>& rdlocks,
diff --git a/src/messages/MMDSFindIno.h b/src/messages/MMDSFindIno.h
new file mode 100644 (file)
index 0000000..204aa85
--- /dev/null
@@ -0,0 +1,44 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+#ifndef CEPH_MDSFINDINO_H
+#define CEPH_MDSFINDINO_H
+
+#include "msg/Message.h"
+#include "include/filepath.h"
+
+struct MMDSFindIno : public Message {
+  tid_t tid;
+  inodeno_t ino;
+
+  MMDSFindIno() : Message(MSG_MDS_FINDINO) {}
+  MMDSFindIno(tid_t t, inodeno_t i) : Message(MSG_MDS_FINDINO), tid(t), ino(i) {}
+
+  const char *get_type_name() { return "findino"; }
+  void print(ostream &out) {
+    out << "findino(" << tid << " " << ino << ")";
+  }
+
+  void encode_payload() {
+    ::encode(tid, payload);
+    ::encode(ino, payload);
+  }
+  void decode_payload() {
+    bufferlist::iterator p = payload.begin();
+    ::decode(tid, p);
+    ::decode(ino, p);
+  }
+};
+
+#endif
diff --git a/src/messages/MMDSFindInoReply.h b/src/messages/MMDSFindInoReply.h
new file mode 100644 (file)
index 0000000..a3b3460
--- /dev/null
@@ -0,0 +1,44 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+#ifndef CEPH_MDSFINDINOREPLY_H
+#define CEPH_MDSFINDINOREPLY_H
+
+#include "msg/Message.h"
+#include "include/filepath.h"
+
+struct MMDSFindInoReply : public Message {
+  tid_t tid;
+  filepath path;
+
+  MMDSFindInoReply() : Message(MSG_MDS_FINDINOREPLY) {}
+  MMDSFindInoReply(tid_t t) : Message(MSG_MDS_FINDINOREPLY), tid(t) {}
+
+  const char *get_type_name() { return "findinoreply"; }
+  void print(ostream &out) {
+    out << "findinoreply(" << tid << " " << path << ")";
+  }
+  
+  void encode_payload() {
+    ::encode(tid, payload);
+    ::encode(path, payload);
+  }
+  void decode_payload() {
+    bufferlist::iterator p = payload.begin();
+    ::decode(tid, p);
+    ::decode(path, p);
+  }
+};
+
+#endif
index 2f6c37a4699a6d79c5ed86699999e56139815c4f..82ebb4ecdf4d2cb254988237f9d1857bbd02d256 100644 (file)
@@ -88,6 +88,8 @@ using namespace std;
 #include "messages/MMDSResolve.h"
 #include "messages/MMDSResolveAck.h"
 #include "messages/MMDSCacheRejoin.h"
+#include "messages/MMDSFindIno.h"
+#include "messages/MMDSFindInoReply.h"
 
 #include "messages/MDirUpdate.h"
 #include "messages/MDiscover.h"
@@ -414,6 +416,13 @@ Message *decode_message(ceph_msg_header& header, ceph_msg_footer& footer,
     m = new MDiscoverReply();
     break;
 
+  case MSG_MDS_FINDINO:
+    m = new MMDSFindIno;
+    break;
+  case MSG_MDS_FINDINOREPLY:
+    m = new MMDSFindInoReply;
+    break;
+
   case MSG_MDS_FRAGMENTNOTIFY:
     m = new MMDSFragmentNotify;
     break;
index 3758b1be6e1e00d5a9efcae10778facd35c91a21..bd36f04ee8078d8943f4507b53a8aa048b168733 100644 (file)
@@ -96,6 +96,8 @@
 #define MSG_MDS_FRAGMENTNOTIFY     0x209
 #define MSG_MDS_OFFLOAD_TARGETS    0x20a
 #define MSG_MDS_DENTRYLINK         0x20c
+#define MSG_MDS_FINDINO            0x20d
+#define MSG_MDS_FINDINOREPLY       0x20e
 
 #define MSG_MDS_LOCK               0x300
 #define MSG_MDS_INODEFILECAPS      0x301