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;
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);
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())
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
/*
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;
// 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
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:
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;