MDCache::MDCache(MDS *m) :
+ num_strays(0),
+ num_strays_purging(0),
+ num_strays_delayed(0),
recovery_queue(m),
delayed_eval_stray(member_offset(CDentry, item_stray))
{
if (!straydn) {
straydn = straydir->add_null_dentry(straydname);
straydn->mark_new();
- } else
+
+ num_strays++;
+ logger->set(l_mdc_num_strays, num_strays);
+ logger->inc(l_mdc_strays_created);
+ } else {
assert(straydn->get_projected_linkage()->is_null());
+ }
straydn->state_set(CDentry::STATE_STRAY);
return straydn;
CDentry *dn = *p;
++p;
dn->item_stray.remove_myself();
+ num_strays_delayed--;
eval_stray(dn);
}
+ logger->set(l_mdc_num_strays_delayed, num_strays_delayed);
map<mds_rank_t, MCacheExpire*> expiremap;
bool is_standby_replay = mds->is_standby_replay();
for (CDir::map_t::iterator q = dir->items.begin(); q != dir->items.end(); ++q) {
CDentry *dn = q->second;
CDentry::linkage_t *dnl = dn->get_projected_linkage();
+ num_strays++;
if (dnl->is_primary())
maybe_eval_stray(dnl->get_inode());
}
return;
}
if (delay) {
- if (!dn->item_stray.is_on_list())
+ if (!dn->item_stray.is_on_list()) {
delayed_eval_stray.push_back(&dn->item_stray);
+ num_strays_delayed++;
+ logger->set(l_mdc_num_strays_delayed, num_strays_delayed);
+ }
} else {
if (in->is_dir())
in->close_dirfrags();
dn->get(CDentry::PIN_PURGING);
in->state_set(CInode::STATE_PURGING);
- if (dn->item_stray.is_on_list())
+ num_strays_purging++;
+ logger->set(l_mdc_num_strays_purging, num_strays_purging);
+
+ if (dn->item_stray.is_on_list()) {
dn->item_stray.remove_myself();
+ num_strays_delayed--;
+ logger->set(l_mdc_num_strays_delayed, num_strays_delayed);
+ }
if (in->is_dirty_parent())
in->clear_dirty_parent();
le->metablob.add_destroyed_inode(in->ino());
mds->mdlog->submit_entry(le, new C_MDC_PurgeStrayLogged(this, dn, pdv, mds->mdlog->get_current_segment()));
+
+ num_strays_purging--;
+ num_strays--;
+ logger->set(l_mdc_num_strays, num_strays);
+ logger->set(l_mdc_num_strays_purging, num_strays_purging);
+ logger->inc(l_mdc_strays_purged);
} else {
// new refs.. just truncate to 0
EUpdate *le = new EUpdate(mds->mdlog, "purge_stray truncate");
return;
in->flush(new C_FinishIOMDR(mds, mdr));
}
+
+
+/**
+ * Initialize performance counters with global perfcounter
+ * collection.
+ */
+void MDCache::register_perfcounters()
+{
+ PerfCountersBuilder pcb(g_ceph_context,
+ "mds_cache", l_mdc_first, l_mdc_last);
+
+ /* Stray/purge statistics */
+ pcb.add_u64(l_mdc_num_strays, "num_strays");
+ pcb.add_u64(l_mdc_num_strays_purging, "num_strays_purging");
+ pcb.add_u64(l_mdc_num_strays_delayed, "num_strays_delayed");
+ pcb.add_u64_counter(l_mdc_strays_created, "strays_created");
+ pcb.add_u64_counter(l_mdc_strays_purged, "strays_purged");
+
+ logger = pcb.create_perf_counters();
+ g_ceph_context->get_perfcounters_collection()->add(logger);
+}
+
typedef ceph::shared_ptr<MDRequestImpl> MDRequestRef;
struct MDSlaveUpdate;
+enum {
+ l_mdc_first = 3000,
+ // How many dentries are currently in stray dirs
+ l_mdc_num_strays,
+ // How many stray dentries are currently being purged
+ l_mdc_num_strays_purging,
+ // How many stray dentries are currently delayed for purge due to refs
+ l_mdc_num_strays_delayed,
+ // How many dentries have ever been added to stray dir
+ l_mdc_strays_created,
+ // How many dentries have ever finished purging from stray dir
+ l_mdc_strays_purged,
+ l_mdc_last,
+};
+
// flags for predirty_journal_parents()
static const int PREDIRTY_PRIMARY = 1; // primary dn, adjust nested accounting
set<CInode*> base_inodes;
+ PerfCounters *logger;
+
public:
void advance_stray() {
stray_index = (stray_index+1)%NUM_STRAY;
int num_inodes_with_caps;
int num_caps;
+ uint64_t num_strays;
+ uint64_t num_strays_purging;
+ uint64_t num_strays_delayed;
+
unsigned max_dir_commit_size;
ceph_file_layout default_file_layout;
ceph_file_layout default_log_layout;
+ void register_perfcounters();
+
// -- client leases --
public:
static const int client_lease_pools = 3;