}
}
+// get caps for a given file handle -- the inode should have @need caps
+// issued by the mds and @want caps not revoked (or not under revocation).
+// this routine blocks till the cap requirement is satisfied. also account
+// (track) for capability hit when required (when cap requirement succeedes).
int Client::get_caps(Fh *fh, int need, int want, int *phave, loff_t endoff)
{
Inode *in = fh->inode.get();
if ((revoking & want) == 0) {
*phave = need | (have & want);
in->get_cap_ref(need);
+ cap_hit();
return 0;
}
}
void flush_cap_releases();
void tick();
+ void cap_hit() {
+ ++cap_hits;
+ }
+ void cap_miss() {
+ ++cap_misses;
+ }
+ std::pair<uint64_t, uint64_t> get_cap_hit_rates() {
+ return std::make_pair(cap_hits, cap_misses);
+ }
+
xlist<Inode*> &get_dirty_list() { return dirty_list; }
SafeTimer timer;
int reclaim_errno = 0;
epoch_t reclaim_osd_epoch = 0;
entity_addrvec_t reclaim_target_addrs;
+
+ uint64_t cap_hits = 0;
+ uint64_t cap_misses = 0;
};
/**
* This is the bog standard "check whether we have the required caps" operation.
* Typically, we only check against the capset that is currently "issued".
* In other words, we ignore caps that have been revoked but not yet released.
+ * Also account capability hit/miss stats.
*
* Some callers (particularly those doing attribute retrieval) can also make
* use of the full set of "implemented" caps to satisfy requests from the
cap_is_valid(*auth_cap) &&
(auth_cap->issued & mask) == mask) {
auth_cap->touch();
+ client->cap_hit();
return true;
}
// try any cap
if (cap_is_valid(cap)) {
if ((cap.issued & mask) == mask) {
cap.touch();
+ client->cap_hit();
return true;
}
c |= cap.issued;
for (auto &pair : caps) {
pair.second.touch();
}
+ client->cap_hit();
return true;
}
+
+ client->cap_miss();
return false;
}