]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: synchronize metadata on fsync, when requested.
authorGreg Farnum <gregf@hq.newdream.net>
Fri, 2 Jul 2010 18:28:21 +0000 (11:28 -0700)
committerGreg Farnum <gregf@hq.newdream.net>
Fri, 2 Jul 2010 18:30:46 +0000 (11:30 -0700)
src/client/Client.cc
src/client/Client.h

index e2d3e0faf18d07c10c9d08c4f67b6603989e7703..070177523bf629748bde3f5dc194815c173c6834 100644 (file)
@@ -2199,6 +2199,21 @@ void Client::flush_caps()
     check_caps(in, true);
   }
 }
+
+void Client::flush_caps(Inode *in, int mds) {
+  dout(10) << "flush_caps(inode:" << in << ", mds" << mds << ")" << dendl;
+  InodeCap *cap = in->caps[mds];
+  int wanted = in->caps_wanted();
+  int flush = wanted | CEPH_CAP_PIN;
+  int flush_tid = ++in->last_flush_tid;
+  //set up flush tid stores
+  for (int i = 0; i < CEPH_CAP_BITS; ++i) {
+    if (flush & (1<<i))
+      in->flushing_cap_tid[i] = flush_tid;
+  }
+  send_cap(in, mds, cap, in->caps_used(), wanted, flush, in->dirty_caps, flush_tid);
+}
+
 void Client::wait_sync_caps(uint64_t want)
 {
  retry:
@@ -4695,21 +4710,34 @@ int Client::_fsync(Fh *f, bool syncdataonly)
   int r = 0;
 
   Inode *in = f->inode;
+  tid_t wait_on_flush = 0;
+  bool flushed_metadata = false;
 
   dout(3) << "_fsync(" << f << ", " << (syncdataonly ? "dataonly)":"data+metadata)") << dendl;
   
-  // metadata?
-  if (!syncdataonly)
-    dout(0) << "fsync - not syncing metadata yet.. implement me" << dendl;
-
   if (g_conf.client_oc)
     _flush(in);
   
+  if (!syncdataonly && (in->dirty_caps & ~CEPH_CAP_ANY_FILE_WR)) {
+    for (map<int, InodeCap*>::iterator iter = in->caps.begin(); iter != in->caps.end(); ++iter) {
+      if (iter->second->implemented & ~CEPH_CAP_ANY_FILE_WR) {
+        flush_caps(in, iter->first);
+      }
+    }
+    wait_on_flush = in->last_flush_tid;
+    flushed_metadata = true;
+4  } else dout(10) << "no metadata needs to commit" << dendl;
+
+
   while (in->cap_refs[CEPH_CAP_FILE_BUFFER] > 0) {
     dout(10) << "ino " << in->ino << " has " << in->cap_refs[CEPH_CAP_FILE_BUFFER]
             << " uncommitted, waiting" << dendl;
     wait_on_list(in->waitfor_commit);
-  }    
+  }
+
+  if (!flushed_metadata) wait_sync_caps(wait_on_flush); //this could wait longer than strictly necessary,
+                                                    //but on a sync the user can put up with it
+
   dout(10) << "ino " << in->ino << " has no uncommitted writes" << dendl;
 
   return r;
index 7d49f4c6402cc3e4c2d86bd5f97ec6154fd14af4..81c914e9379a8fe3543e41b19b5440c8413d00a4 100644 (file)
@@ -1041,6 +1041,7 @@ protected:
   void trim_caps(int mds, int max);
   void mark_caps_dirty(Inode *in, int caps);
   void flush_caps();
+  void flush_caps(Inode *in, int mds);
   void kick_flushing_caps(int mds);
   int get_caps(Inode *in, int need, int want, int *got, loff_t endoff);