]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mds: fix CDir::log_mark_dirty()
authorYan, Zheng <zyan@redhat.com>
Fri, 21 Oct 2016 03:38:44 +0000 (11:38 +0800)
committerYan, Zheng <zyan@redhat.com>
Fri, 21 Oct 2016 06:40:53 +0000 (14:40 +0800)
CDir::log_mark_dirty() moves dirfrag to current log segment's dirty
dirfrag list, but it does not submit any log event. Old log segments
(that include events which dirty the dirfrag) may get expired before
the dirfrag gets committed. If MDS crashes, the changes in expired
log segments get lost.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/CDir.cc

index 7d101ce44b73e775cf71fb803bf4a752b16a2370..6e719da3532b54679aaec112f6344e1a5cf03d61 100644 (file)
@@ -1357,24 +1357,14 @@ void CDir::mark_clean()
   }
 }
 
-
-struct C_Dir_Dirty : public CDirContext {
-  version_t pv;
-  LogSegment *ls;
-  C_Dir_Dirty(CDir *d, version_t p, LogSegment *l) : CDirContext(d), pv(p), ls(l) {}
-  void finish(int r) {
-    dir->mark_dirty(pv, ls);
-    dir->auth_unpin(dir);
-  }
-};
-
 // caller should hold auth pin of this
 void CDir::log_mark_dirty()
 {
-  MDLog *mdlog = inode->mdcache->mds->mdlog;
+  if (is_dirty() || is_projected())
+    return; // noop if it is already dirty or will be dirty
+
   version_t pv = pre_dirty();
-  mdlog->flush();
-  mdlog->wait_for_safe(new C_Dir_Dirty(this, pv, mdlog->get_current_segment()));
+  mark_dirty(pv, cache->mds->mdlog->get_current_segment());
 }
 
 void CDir::mark_complete() {
@@ -1878,10 +1868,10 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
   }
 
   // dirty myself to remove stale snap dentries
-  if (force_dirty && !is_dirty() && !inode->mdcache->is_readonly())
+  if (force_dirty && !inode->mdcache->is_readonly())
     log_mark_dirty();
-  else
-    auth_unpin(this);
+
+  auth_unpin(this);
 
   if (complete) {
     // kick waiters