]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
filer: make probe recover size and/or mtime; fix some bugs
authorSage Weil <sage@newdream.net>
Mon, 18 May 2009 23:51:29 +0000 (16:51 -0700)
committerSage Weil <sage@newdream.net>
Mon, 18 May 2009 23:52:30 +0000 (16:52 -0700)
This fixes up MDS recovery to find the file size.  And makes
probe actually work.. it was pretty broken before.

src/client/SyntheticClient.cc
src/mds/MDCache.cc
src/mds/MDSTable.cc
src/osdc/Filer.cc
src/osdc/Filer.h
src/osdc/Journaler.cc
src/osdc/Objecter.cc
src/osdc/Objecter.h

index db10860889ff7127e1cb54c3401402f5aa6c95ad..a77fb330657a9b278906b5ee394c000b516d71b7 100644 (file)
@@ -1347,7 +1347,8 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only)
       lock.Lock();
       ceph_object_layout layout = client->osdmap->make_object_layout(oid, CEPH_CASDATA_RULE);
       __u64 size;
-      client->objecter->stat(oid, layout, &size, 0, new C_SafeCond(&lock, &cond, &ack));
+      utime_t mtime;
+      client->objecter->stat(oid, layout, &size, &mtime, 0, new C_SafeCond(&lock, &cond, &ack));
       while (!ack) cond.Wait(lock);
       lock.Unlock();
     }
index 616d65e760d09aa166bfd7b3feae226e834f8135..2cddbe23320350be410d4ce8adc77fb92f19fe57 100644 (file)
@@ -4331,7 +4331,7 @@ void MDCache::do_file_recover()
               << " " << *in << dendl;
       file_recovering.insert(in);
       mds->filer->probe(in->inode.ino, &in->inode.layout, in->last,
-                       in->inode.max_size, &in->inode.size, false,
+                       in->inode.max_size, &in->inode.size, &in->inode.mtime, false,
                        0, new C_MDC_Recover(this, in));    
     } else {
       dout(10) << "do_file_recover skipping " << in->inode.size << "/" << in->inode.max_size 
@@ -4345,7 +4345,8 @@ void MDCache::do_file_recover()
 
 void MDCache::_recovered(CInode *in, int r)
 {
-  dout(10) << "_recovered r=" << r << " size=" << in->inode.size << " for " << *in << dendl;
+  dout(10) << "_recovered r=" << r << " size=" << in->inode.size << " mtime=" << in->inode.mtime
+          << " for " << *in << dendl;
 
   file_recovering.erase(in);
   in->state_clear(CInode::STATE_RECOVERING);
index ff80fcb38f58c1ed7361e2b79d4d85476becab4f..b8fd07ef6a3c8fdecd55fd3317022ddaba775c21 100644 (file)
@@ -133,7 +133,7 @@ void MDSTable::load_2(int r, bufferlist& bl, Context *onfinish)
   assert(is_opening());
   state = STATE_ACTIVE;
 
-  if (r > 0) {
+  if (r >= 0) {
     dout(10) << "load_2 got " << bl.length() << " bytes" << dendl;
     bufferlist::iterator p = bl.begin();
     ::decode(version, p);
index 309bc97db66d58433837518657efff85b6640f65..88fbaacd6e8cbc8be0e08c31eb05f853e9e672f9 100644 (file)
@@ -37,9 +37,10 @@ public:
   Probe *probe;
   object_t oid;
   __u64 size;
+  utime_t mtime;
   C_Probe(Filer *f, Probe *p, object_t o) : filer(f), probe(p), oid(o), size(0) {}
   void finish(int r) {
-    filer->_probed(probe, oid, size);    
+    filer->_probed(probe, oid, size, mtime);    
   }  
 };
 
@@ -48,6 +49,7 @@ int Filer::probe(inodeno_t ino,
                 snapid_t snapid,
                 __u64 start_from,
                 __u64 *end,           // LB, when !fwd
+                utime_t *pmtime,
                 bool fwd,
                 int flags,
                 Context *onfinish) 
@@ -59,7 +61,7 @@ int Filer::probe(inodeno_t ino,
 
   assert(snapid);  // (until there is a non-NOSNAP write)
 
-  Probe *probe = new Probe(ino, *layout, snapid, start_from, end, flags, fwd, onfinish);
+  Probe *probe = new Probe(ino, *layout, snapid, start_from, end, pmtime, flags, fwd, onfinish);
   
   // period (bytes before we jump unto a new set of object(s))
   __u64 period = ceph_file_layout_period(*layout);
@@ -73,7 +75,7 @@ int Filer::probe(inodeno_t ino,
     assert(start_from > *end);
     if (start_from % period)
       probe->probing_len -= period - (start_from % period);
-    probe->from -= probe->probing_len;
+    probe->probing_off -= probe->probing_len;
   }
   
   _probe(probe);
@@ -84,26 +86,33 @@ int Filer::probe(inodeno_t ino,
 void Filer::_probe(Probe *probe)
 {
   dout(10) << "_probe " << hex << probe->ino << dec 
-          << " " << probe->from << "~" << probe->probing_len 
+          << " " << probe->probing_off << "~" << probe->probing_len 
           << dendl;
   
   // map range onto objects
-  file_to_extents(probe->ino, &probe->layout, probe->snapid, probe->from, probe->probing_len, probe->probing);
+  probe->known_size.clear();
+  probe->probing.clear();
+  file_to_extents(probe->ino, &probe->layout, probe->snapid,
+                 probe->probing_off, probe->probing_len, probe->probing);
   
   for (vector<ObjectExtent>::iterator p = probe->probing.begin();
        p != probe->probing.end();
        p++) {
     dout(10) << "_probe  probing " << p->oid << dendl;
     C_Probe *c = new C_Probe(this, probe, p->oid);
-    probe->ops[p->oid] = objecter->stat(p->oid, p->layout, &c->size, probe->flags, c);
+    probe->ops[p->oid] = objecter->stat(p->oid, p->layout, &c->size, &c->mtime, probe->flags, c);
   }
 }
 
-void Filer::_probed(Probe *probe, object_t oid, __u64 size)
+void Filer::_probed(Probe *probe, object_t oid, __u64 size, utime_t mtime)
 {
-  dout(10) << "_probed " << probe->ino << " object " << hex << oid << dec << " has size " << size << dendl;
+  dout(10) << "_probed " << probe->ino << " object " << oid
+          << " has size " << size << " mtime " << mtime << dendl;
+
+  probe->known_size[oid] = size;
+  if (mtime > probe->max_mtime)
+    probe->max_mtime = mtime;
 
-  probe->known[oid] = size;
   assert(probe->ops.count(oid));
   probe->ops.erase(oid);
 
@@ -111,7 +120,6 @@ void Filer::_probed(Probe *probe, object_t oid, __u64 size)
     return;  // waiting for more!
 
   // analyze!
-  bool found = false;
   __u64 end = 0;
 
   if (!probe->fwd) {
@@ -130,63 +138,73 @@ void Filer::_probed(Probe *probe, object_t oid, __u64 size)
     __u64 shouldbe = p->length + p->offset;
     dout(10) << "_probed  " << probe->ino << " object " << hex << p->oid << dec
             << " should be " << shouldbe
-            << ", actual is " << probe->known[p->oid]
+            << ", actual is " << probe->known_size[p->oid]
             << dendl;
 
-    if (probe->known[p->oid] < 0) { end = -1; break; } // error!
-
-    assert(probe->known[p->oid] <= shouldbe);
-    if (shouldbe == probe->known[p->oid] && probe->fwd)
-      continue;  // keep going
-   
-    // aha, we found the end!
-    // calc offset into buffer_extent to get distance from probe->from.
-    __u64 oleft = probe->known[p->oid] - p->offset;
-    for (map<__u32,__u32>::iterator i = p->buffer_extents.begin();
-        i != p->buffer_extents.end();
-        i++) {
-      if (oleft <= (__u64)i->second) {
-       end = probe->from + i->first + oleft;
-       found = true;
-       dout(10) << "_probed  end is in buffer_extent " << i->first << "~" << i->second << " off " << oleft 
-                << ", from was " << probe->from << ", end is " << end 
-                << dendl;
-       break;
+    // error?
+    if (probe->known_size[p->oid] < 0) {
+      probe->err = probe->known_size[p->oid];
+      break;
+    }
+
+    if (!probe->found_size) {
+      assert(probe->known_size[p->oid] <= shouldbe);
+
+      if ((probe->fwd && probe->known_size[p->oid] == shouldbe) ||
+         (!probe->fwd && probe->known_size[p->oid] == 0))
+       continue;  // keep going
+      
+      // aha, we found the end!
+      // calc offset into buffer_extent to get distance from probe->from.
+      __u64 oleft = probe->known_size[p->oid] - p->offset;
+      for (map<__u32,__u32>::iterator i = p->buffer_extents.begin();
+          i != p->buffer_extents.end();
+          i++) {
+       if (oleft <= (__u64)i->second) {
+         end = probe->probing_off + i->first + oleft;
+         dout(10) << "_probed  end is in buffer_extent " << i->first << "~" << i->second << " off " << oleft 
+                  << ", from was " << probe->probing_off << ", end is " << end 
+                  << dendl;
+         
+         probe->found_size = true;
+         dout(10) << "_probed found size at " << end << dendl;
+         *probe->psize = end;
+         
+         if (!probe->pmtime)  // stop if we don't need mtime too
+           break;
+       }
+       oleft -= i->second;
       }
-      oleft -= i->second;
     }
     break;
   }
 
-  if (!found) {
+  if (!probe->found_size || (probe->probing_off && probe->pmtime)) {
     // keep probing!
-    dout(10) << "_probed didn't find end, probing further" << dendl;
+    dout(10) << "_probed probing further" << dendl;
+
     __u64 period = ceph_file_layout_period(probe->layout);
     if (probe->fwd) {
-      probe->from += probe->probing_len;
-      assert(probe->from % period == 0);
+      probe->probing_off += probe->probing_len;
+      assert(probe->probing_off % period == 0);
       probe->probing_len = period;
     } else {
       // previous period.
-      assert(probe->from % period == 0);
-      probe->probing_len -= period;
-      probe->from -= period;
+      assert(probe->probing_off % period == 0);
+      probe->probing_len = period;
+      probe->probing_off -= period;
     }
     _probe(probe);
     return;
   }
 
-  if (end < 0) {
-    dout(10) << "_probed encountered an error while probing" << dendl;
-    *probe->end = -1;
-  } else {
-    // hooray!
-    dout(10) << "_probed found end at " << end << dendl;
-    *probe->end = end;
+  if (probe->pmtime) {
+    dout(10) << "_probed found mtime " << probe->max_mtime << dendl;
+    *probe->pmtime = probe->max_mtime;
   }
 
   // done!  finish and clean up.
-  probe->onfinish->finish(end >= 0 ? 0:-1);
+  probe->onfinish->finish(probe->err);
   delete probe->onfinish;
   delete probe;
 }
index 6fd1ae5dcece7a8a7c15520ad5595e6827817766..476b86dc7acf9e14309e458924e7c9bd74d63939 100644 (file)
@@ -46,8 +46,10 @@ class Filer {
     inodeno_t ino;
     ceph_file_layout layout;
     snapid_t snapid;
-    __u64 from;        // for !fwd, this is start of extent we are probing, thus possibly < our endpoint.
-    __u64 *end;
+
+    __u64 *psize;
+    utime_t *pmtime;
+
     int flags;
 
     bool fwd;
@@ -55,21 +57,28 @@ class Filer {
     Context *onfinish;
     
     vector<ObjectExtent> probing;
-    __u64 probing_len;
+    __u64 probing_off, probing_len;
     
-    map<object_t, __u64> known;
+    map<object_t, __u64> known_size;
+    utime_t max_mtime;
+
     map<object_t, tid_t> ops;
 
+    int err;
+    bool found_size;
+
     Probe(inodeno_t i, ceph_file_layout &l, snapid_t sn,
-         __u64 f, __u64 *e, int fl, bool fw, Context *c) : 
+         __u64 f, __u64 *e, utime_t *m, int fl, bool fw, Context *c) : 
       ino(i), layout(l), snapid(sn),
-      from(f), end(e), flags(fl), fwd(fw), onfinish(c), probing_len(0) {}
+      psize(e), pmtime(m), flags(fl), fwd(fw), onfinish(c),
+      probing_off(f), probing_len(0),
+      err(0), found_size(false) {}
   };
   
   class C_Probe;
 
   void _probe(Probe *p);
-  void _probed(Probe *p, object_t oid, __u64 size);
+  void _probed(Probe *p, object_t oid, __u64 size, utime_t mtime);
 
  public:
   Filer(Objecter *o) : objecter(o) {}
@@ -237,10 +246,10 @@ class Filer {
            snapid_t snapid,
            __u64 start_from,
            __u64 *end,
+           utime_t *mtime,
            bool fwd,
            int flags,
            Context *onfinish);
-
 };
 
 
index 52726f2a337b1d11964c0552e9c9ed4f20c3b04f..625ea3f9b1a4380d6f4cd2ac6c40da3b4fda232c 100644 (file)
@@ -146,7 +146,7 @@ void Journaler::_finish_read_head(int r, bufferlist& bl)
   state = STATE_PROBING;
   C_ProbeEnd *fin = new C_ProbeEnd(this);
   filer.probe(ino, &layout, CEPH_NOSNAP,
-             h.write_pos, (__u64 *)&fin->end, true, CEPH_OSD_FLAG_INCLOCK_FAIL, fin);
+             h.write_pos, (__u64 *)&fin->end, 0, true, CEPH_OSD_FLAG_INCLOCK_FAIL, fin);
 }
 
 void Journaler::_finish_probe_end(int r, __s64 end)
index 97b81890c547933bddf71549eeea82ee56763308..e96e88c6272ca7dd3b83a3b28350ca2487775b0f 100644 (file)
@@ -460,7 +460,6 @@ void Objecter::handle_osd_read_reply(MOSDOpReply *m)
   dout(7) << " got reply on " << rd->ops << dendl;
 
   int bytes_read = m->get_data().length();
-
   if (rd->pbl)
     rd->pbl->claim(m->get_data());
 
@@ -471,7 +470,7 @@ void Objecter::handle_osd_read_reply(MOSDOpReply *m)
   // done
   delete rd;
   if (onfinish) {
-    onfinish->finish(bytes_read);// > 0 ? bytes_read:m->get_result());
+    onfinish->finish(m->get_result());
     delete onfinish;
   }
   delete m;
index 95047f5e39d2804c16ffe4f2eec957cdd7ab3022..fd3d4cb0745a3961759406501196ec311087f1b7 100644 (file)
@@ -350,7 +350,7 @@ class Objecter {
 
   // high-level helpers
   tid_t stat(object_t oid, ceph_object_layout ol,
-            __u64 *psize, int flags, 
+            __u64 *psize, utime_t *pmtime, int flags, 
             Context *onfinish) {
     vector<ceph_osd_op> ops(1);
     memset(&ops[0], 0, sizeof(ops[0]));