p.second.dirty_data = 0;
signal_context_list(in->waitfor_commit);
ldout(cct, 5) << __func__ << " dropped last FILE_BUFFER ref on " << *in << dendl;
- ++put_nref;
+ if (!in->is_write_delegated()) {
+ ++put_nref;
+ }
if (!in->cap_snaps.empty()) {
flush_snaps(in);
ldout(cct, 15) << "got " << r << " from flush writeback" << dendl;
} else {
// FIXME: this can starve
- int nr_refs = 0;
- if (in->is_write_delegated()) {
- ++nr_refs;
- }
- while (in->cap_refs[CEPH_CAP_FILE_BUFFER] > nr_refs) {
+ while (!in->is_last_cap_ref(CEPH_CAP_FILE_BUFFER)) {
ldout(cct, 10) << "ino " << in->ino << " has " << in->cap_refs[CEPH_CAP_FILE_BUFFER]
- << " uncommitted (nrefs: " << nr_refs << "), waiting" << dendl;
+ << " uncommitted, waiting" << dendl;
wait_on_context_list(in->waitfor_commit);
}
}
}
}
+bool Inode::is_last_cap_ref(int c)
+{
+ if (c != CEPH_CAP_FILE_BUFFER) {
+ return cap_refs[c] == 0;
+ }
+
+ int nref = 0;
+ if (is_write_delegated()) {
+ ++nref;
+ }
+
+ return cap_refs[c] == nref;
+}
+
int Inode::put_cap_ref(int cap)
{
int last = 0;
lderr(client->cct) << "put_cap_ref " << ccap_string(c) << " went negative on " << *this << dendl;
ceph_assert(cap_refs[c] > 0);
}
- if (--cap_refs[c] == 0)
+ --cap_refs[c];
+ if (is_last_cap_ref(c))
last |= c;
//cout << "inode " << *this << " put " << cap_string(c) << " " << (cap_refs[c]+1) << " -> " << cap_refs[c] << std::endl;
}
void get_cap_ref(int cap);
int put_cap_ref(int cap);
+ bool is_last_cap_ref(int c);
bool is_any_caps();
bool cap_is_valid(const Cap &cap) const;
int caps_issued(int *implemented = 0) const;