]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: don't blindly create empty object when dirfrag is missing
authorYan, Zheng <zyan@redhat.com>
Fri, 24 Oct 2014 23:55:54 +0000 (16:55 -0700)
committerYan, Zheng <zyan@redhat.com>
Tue, 2 Dec 2014 02:48:31 +0000 (10:48 +0800)
mark the corresponding CDir as bad instead.

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

index 7fc2ae41562121b6e420dcceb150800597a9f59c..fb9bce83584f6255b2ced6b6cb5510db093ba3f2 100644 (file)
@@ -121,6 +121,7 @@ ostream& operator<<(ostream& out, CDir& dir)
   if (dir.state_test(CDir::STATE_FREEZINGDIR)) out << "|freezingdir";
   if (dir.state_test(CDir::STATE_EXPORTBOUND)) out << "|exportbound";
   if (dir.state_test(CDir::STATE_IMPORTBOUND)) out << "|importbound";
+  if (dir.state_test(CDir::STATE_BADFRAG)) out << "|badfrag";
 
   // fragstat
   out << " " << dir.fnode.fragstat;
@@ -1483,8 +1484,7 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
     dout(0) << "_fetched missing object for " << *this << dendl;
     clog->error() << "dir " << dirfrag() << " object missing on disk; some files may be lost\n";
 
-    log_mark_dirty();
-
+    state_set(STATE_BADFRAG);
     // mark complete, !fetching
     mark_complete();
     state_clear(STATE_FETCHING);
@@ -1866,6 +1866,11 @@ void CDir::_omap_commit(int op_prio)
     if (write_size >= max_write_size) {
       ObjectOperation op;
       op.priority = op_prio;
+
+      // don't create new dirfrag blindly
+      if (!is_new() && !state_test(CDir::STATE_FRAGMENTING))
+       op.stat(NULL, (utime_t*)NULL, NULL);
+
       op.tmap_to_omap(true); // convert tmap to omap
 
       if (!to_set.empty())
@@ -1884,6 +1889,11 @@ void CDir::_omap_commit(int op_prio)
 
   ObjectOperation op;
   op.priority = op_prio;
+
+  // don't create new dirfrag blindly
+  if (!is_new() && !state_test(CDir::STATE_FRAGMENTING))
+    op.stat(NULL, (utime_t*)NULL, NULL);
+
   op.tmap_to_omap(true); // convert tmap to omap
 
   /*
index a4d617efe294212dd17a10a5c2c841a662a544ed..799e3be239cdf52cdddde4787fa31e36339fcdc3 100644 (file)
@@ -106,6 +106,7 @@ public:
   static const unsigned STATE_DNPINNEDFRAG =  (1<<16);  // dir is refragmenting
   static const unsigned STATE_ASSIMRSTAT =    (1<<17);  // assimilating inode->frag rstats
   static const unsigned STATE_DIRTYDFT =      (1<<18);  // dirty dirfragtree
+  static const unsigned STATE_BADFRAG =       (1<<19);  // bad dirfrag
 
   // common states
   static const unsigned STATE_CLEAN =  0;
@@ -114,7 +115,7 @@ public:
   // these state bits are preserved by an import/export
   // ...except if the directory is hashed, in which case none of them are!
   static const unsigned MASK_STATE_EXPORTED = 
-  (STATE_COMPLETE|STATE_DIRTY|STATE_DIRTYDFT);
+  (STATE_COMPLETE|STATE_DIRTY|STATE_DIRTYDFT|STATE_BADFRAG);
   static const unsigned MASK_STATE_IMPORT_KEPT = 
   (                                              
    STATE_IMPORTING
@@ -220,6 +221,8 @@ public:
   bool is_new() { return item_new.is_on_list(); }
   void mark_new(LogSegment *ls);
 
+  bool is_bad() { return state_test(STATE_BADFRAG); }
+
 public:
   typedef std::map<dentry_key_t, CDentry*> map_t;
 protected:
index ca3656e9b96023cfe43ab97f5e55a97eb0c4c1d6..963b04fc0285218a9a8a8d668bcee2763f3860ea 100644 (file)
@@ -10471,6 +10471,10 @@ bool MDCache::can_fragment(CInode *diri, list<CDir*>& dirs)
       dout(7) << "can_fragment: not auth on " << *dir << dendl;
       return false;
     }
+    if (dir->is_bad()) {
+      dout(7) << "can_fragment: bad dirfrag " << *dir << dendl;
+      return false;
+    }
     if (dir->is_frozen() ||
        dir->is_freezing()) {
       dout(7) << "can_fragment: can't merge, freezing|frozen.  wait for other exports to finish first." << dendl;