From: Yan, Zheng Date: Fri, 24 Oct 2014 23:55:54 +0000 (-0700) Subject: mds: don't blindly create empty object when dirfrag is missing X-Git-Tag: v0.91~52^2~14^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=131f0922fcc4c0300758a81d6d35a170dcae1bbb;p=ceph.git mds: don't blindly create empty object when dirfrag is missing mark the corresponding CDir as bad instead. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 7fc2ae415621..fb9bce83584f 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -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& 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 /* diff --git a/src/mds/CDir.h b/src/mds/CDir.h index a4d617efe294..799e3be239cd 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -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 map_t; protected: diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index ca3656e9b960..963b04fc0285 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -10471,6 +10471,10 @@ bool MDCache::can_fragment(CInode *diri, list& 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;