int revoking = implemented & ~have;
ldout(cct, 10) << "get_caps " << *in << " have " << ccap_string(have)
<< " need " << ccap_string(need) << " want " << ccap_string(want)
- << " but not " << ccap_string(butnot) << " revoking " << ccap_string(revoking)
+ << " but not " << ccap_string(butnot) << " revoking " << ccap_string(revoking)
<< dendl;
if ((revoking & butnot) == 0) {
*got = need | (have & want);
}
};
-
bool Client::_flush(Inode *in)
{
ldout(cct, 10) << "_flush " << *in << dendl;
- if (!in->oset.dirty_tx && in->oset.uncommitted.empty()) {
+ if (!in->oset.dirty_or_tx) {
ldout(cct, 10) << " nothing to flush" << dendl;
return true;
}
if (cct->_conf->client_oc && (got & CEPH_CAP_FILE_BUFFER)) {
// do buffered write
- if (!in->oset.dirty_tx && in->oset.uncommitted.empty())
+ if (!in->oset.dirty_or_tx)
get_cap_ref(in, CEPH_CAP_FILE_BUFFER);
get_cap_ref(in, CEPH_CAP_FILE_BUFFER);
if (in.flags & I_COMPLETE)
out << " COMPLETE";
+ if (in.is_file())
+ out << " " << in.oset;
+
set<Dentry*>::iterator i = in.dn_set.begin();
while(i != in.dn_set.end()) {
out << " parent=" << *i;
return final;
}
-
void ObjectCacher::Object::truncate(loff_t s)
{
- ldout(oc->cct, 10) << "truncate to " << s << dendl;
-
+ ldout(oc->cct, 10) << "truncate " << *this << " to " << s << dendl;
+
while (!data.empty()) {
- BufferHead *bh = data.rbegin()->second;
- if (bh->end() <= s)
- break;
-
- // split bh at truncation point?
- if (bh->start() < s) {
- split(bh, s);
- continue;
- }
+ BufferHead *bh = data.rbegin()->second;
+ if (bh->end() <= s)
+ break;
+
+ // split bh at truncation point?
+ if (bh->start() < s) {
+ split(bh, s);
+ continue;
+ }
- // remove bh entirely
- assert(bh->start() >= s);
- oc->bh_remove(this, bh);
- delete bh;
+ // remove bh entirely
+ assert(bh->start() >= s);
+ oc->bh_remove(this, bh);
+ delete bh;
}
}
-
-
/*** ObjectCacher ***/
#undef dout_prefix
#define dout_prefix *_dout << objecter->messenger->get_myname() << ".objectcacher "
-
/* private */
void ObjectCacher::close_object(Object *ob)
oncommit->tid = tid;
bh->ob->last_write_tid = tid;
bh->last_write_tid = tid;
- if (commit_set_callback)
- oset->uncommitted.push_back(&bh->ob->uncommitted_item);
mark_tx(bh);
}
}
// is the entire object set now clean?
- if (flush_set_callback && ob->oset->dirty_tx == 0) {
+ if (flush_set_callback && ob->oset->dirty_or_tx == 0) {
flush_set_callback(flush_set_callback_arg, ob->oset);
}
}
// is the entire object set now clean and fully committed?
if (commit_set_callback &&
ob->last_commit_tid == ob->last_write_tid) {
- ob->uncommitted_item.remove_myself();
ObjectSet *oset = ob->oset;
if (ob->can_close())
close_object(ob);
- if (oset->uncommitted.empty()) { // no uncommitted in flight
- if (oset->dirty_tx == 0) // AND nothing dirty/tx
+ if (commit_set_callback) {
+ if (oset->dirty_or_tx == 0) { // nothing dirty/tx
commit_set_callback(flush_set_callback_arg, oset);
+ }
}
}
}
{
ldout(cct, 10) << "purge " << *ob << dendl;
- while (!ob->data.empty()) {
- BufferHead *bh = ob->data.begin()->second;
- if (!bh->is_clean())
- ldout(cct, 0) << "purge forcibly removing " << *ob << " " << *bh << dendl;
- bh_remove(ob, bh);
- delete bh;
- }
-
+ ob->truncate(0);
+
if (ob->can_close()) {
- ldout(cct, 10) << "trim trimming " << *ob << dendl;
+ ldout(cct, 10) << "purge closing " << *ob << dendl;
close_object(ob);
}
}
+
// flush. non-blocking. no callback.
// true if clean, already flushed.
// false if we wrote something.
ldout(cct, 10) << "truncate_set " << oset << dendl;
- bool were_dirty = oset->dirty_tx > 0;
+ bool were_dirty = oset->dirty_or_tx > 0;
for (vector<ObjectExtent>::iterator p = exls.begin();
p != exls.end();
// did we truncate off dirty data?
if (commit_set_callback &&
- were_dirty && oset->dirty_tx == 0)
+ were_dirty && oset->dirty_or_tx == 0)
commit_set_callback(flush_set_callback_arg, oset);
}
tid_t last_ack_tid; // last update acked.
tid_t last_commit_tid; // last update commited.
+ int dirty_or_tx;
+
map< tid_t, list<Context*> > waitfor_ack;
map< tid_t, list<Context*> > waitfor_commit;
list<Context*> waitfor_rd;
list<Context*> waitfor_wr;
- xlist<Object*>::item uncommitted_item;
-
// lock
static const int LOCK_NONE = 0;
static const int LOCK_WRLOCKING = 1;
oc(_oc),
oid(o), oset(os), set_item(this), oloc(l),
last_write_tid(0), last_ack_tid(0), last_commit_tid(0),
- uncommitted_item(this),
+ dirty_or_tx(0),
lock_state(LOCK_NONE), wrlock_ref(0), rdlock_ref(0) {
// add to set
os->objects.push_back(&set_item);
}
~Object() {
assert(data.empty());
+ assert(dirty_or_tx == 0);
set_item.remove_myself();
}
return data.empty() && lock_state == LOCK_NONE &&
waitfor_ack.empty() && waitfor_commit.empty() &&
waitfor_rd.empty() && waitfor_wr.empty() &&
- !uncommitted_item.is_on_list();
+ dirty_or_tx == 0;
}
// bh
int poolid;
xlist<Object*> objects;
- xlist<Object*> uncommitted;
- int dirty_tx;
+ int dirty_or_tx;
ObjectSet(void *p, int _poolid, inodeno_t i) : parent(p), ino(i), truncate_seq(0),
- truncate_size(0), poolid(_poolid), dirty_tx(0) {}
+ truncate_size(0), poolid(_poolid), dirty_or_tx(0) {}
};
break;
case BufferHead::STATE_DIRTY:
stat_dirty += bh->length();
- bh->ob->oset->dirty_tx += bh->length();
+ bh->ob->dirty_or_tx += bh->length();
+ bh->ob->oset->dirty_or_tx += bh->length();
break;
case BufferHead::STATE_TX:
stat_tx += bh->length();
- bh->ob->oset->dirty_tx += bh->length();
+ bh->ob->dirty_or_tx += bh->length();
+ bh->ob->oset->dirty_or_tx += bh->length();
break;
case BufferHead::STATE_RX:
stat_rx += bh->length();
break;
case BufferHead::STATE_DIRTY:
stat_dirty -= bh->length();
- bh->ob->oset->dirty_tx -= bh->length();
+ bh->ob->dirty_or_tx -= bh->length();
+ bh->ob->oset->dirty_or_tx -= bh->length();
break;
case BufferHead::STATE_TX:
stat_tx -= bh->length();
- bh->ob->oset->dirty_tx -= bh->length();
+ bh->ob->dirty_or_tx -= bh->length();
+ bh->ob->oset->dirty_or_tx -= bh->length();
break;
case BufferHead::STATE_RX:
stat_rx -= bh->length();
return out;
}
+inline ostream& operator<<(ostream& out, ObjectCacher::ObjectSet &os)
+{
+ return out << "objectset[" << os.ino
+ << " ts " << os.truncate_seq << "/" << os.truncate_size
+ << " objects " << os.objects.size()
+ << " dirty_or_tx " << os.dirty_or_tx
+ << "]";
+}
+
inline ostream& operator<<(ostream& out, ObjectCacher::Object &ob)
{
out << "object["