max_size(max_bytes), max_objects(max_objects),
flush_set_callback(flush_callback), flush_set_callback_arg(flush_callback_arg),
flusher_stop(false), flusher_thread(this),
- stat_clean(0), stat_dirty(0), stat_rx(0), stat_tx(0), stat_missing(0),
+ stat_clean(0), stat_zero(0), stat_dirty(0), stat_rx(0), stat_tx(0), stat_missing(0),
stat_error(0), stat_dirty_waiting(0)
{
this->max_dirty_age.set_from_double(max_dirty_age);
break;
ldout(cct, 10) << "trim trimming " << *bh << dendl;
- assert(bh->is_clean());
+ assert(bh->is_clean() || bh->is_zero());
Object *ob = bh->ob;
bh_remove(ob, bh);
p != ob->data.end();
p++) {
BufferHead *bh = p->second;
- if (bh->is_clean())
+ if (bh->is_clean() || bh->is_zero())
clean.push_back(bh);
else
o_unclean += bh->length();
{
ldout(cct, 10) << "verify_stats" << dendl;
- loff_t clean = 0, dirty = 0, rx = 0, tx = 0, missing = 0, error = 0;
+ loff_t clean = 0, zero = 0, dirty = 0, rx = 0, tx = 0, missing = 0, error = 0;
for (vector<hash_map<sobject_t, Object*> >::const_iterator i = objects.begin();
i != objects.end();
++i) {
case BufferHead::STATE_CLEAN:
clean += bh->length();
break;
+ case BufferHead::STATE_ZERO:
+ zero += bh->length();
+ break;
case BufferHead::STATE_DIRTY:
dirty += bh->length();
break;
assert(tx == stat_tx);
assert(dirty == stat_dirty);
assert(missing == stat_missing);
+ assert(zero == stat_zero);
assert(error == stat_error);
}
case BufferHead::STATE_CLEAN:
stat_clean += bh->length();
break;
+ case BufferHead::STATE_ZERO:
+ stat_zero += bh->length();
+ break;
case BufferHead::STATE_DIRTY:
stat_dirty += bh->length();
bh->ob->dirty_or_tx += bh->length();
case BufferHead::STATE_CLEAN:
stat_clean -= bh->length();
break;
+ case BufferHead::STATE_ZERO:
+ stat_zero -= bh->length();
+ break;
case BufferHead::STATE_DIRTY:
stat_dirty -= bh->length();
bh->ob->dirty_or_tx -= bh->length();
// states
static const int STATE_MISSING = 0;
static const int STATE_CLEAN = 1;
- static const int STATE_DIRTY = 2;
- static const int STATE_RX = 3;
- static const int STATE_TX = 4;
- static const int STATE_ERROR = 5; // a read error occurred
+ static const int STATE_ZERO = 2;
+ static const int STATE_DIRTY = 3;
+ static const int STATE_RX = 4;
+ static const int STATE_TX = 5;
+ static const int STATE_ERROR = 6; // a read error occurred
private:
// my fields
bool is_missing() { return state == STATE_MISSING; }
bool is_dirty() { return state == STATE_DIRTY; }
bool is_clean() { return state == STATE_CLEAN; }
+ bool is_zero() { return state == STATE_ZERO; }
bool is_tx() { return state == STATE_TX; }
bool is_rx() { return state == STATE_RX; }
bool is_error() { return state == STATE_ERROR; }
Cond stat_cond;
loff_t stat_clean;
+ loff_t stat_zero;
loff_t stat_dirty;
loff_t stat_rx;
loff_t stat_tx;
loff_t get_stat_dirty() { return stat_dirty; }
loff_t get_stat_dirty_waiting() { return stat_dirty_waiting; }
loff_t get_stat_clean() { return stat_clean; }
+ loff_t get_stat_zero() { return stat_zero; }
void touch_bh(BufferHead *bh) {
if (bh->is_dirty())
void mark_missing(BufferHead *bh) { bh_set_state(bh, BufferHead::STATE_MISSING); };
void mark_clean(BufferHead *bh) { bh_set_state(bh, BufferHead::STATE_CLEAN); };
+ void mark_zero(BufferHead *bh) { bh_set_state(bh, BufferHead::STATE_ZERO); };
void mark_rx(BufferHead *bh) { bh_set_state(bh, BufferHead::STATE_RX); };
void mark_tx(BufferHead *bh) { bh_set_state(bh, BufferHead::STATE_TX); };
void mark_error(BufferHead *bh) { bh_set_state(bh, BufferHead::STATE_ERROR); };
if (bh.is_rx()) out << " rx";
if (bh.is_dirty()) out << " dirty";
if (bh.is_clean()) out << " clean";
+ if (bh.is_zero()) out << " zero";
if (bh.is_missing()) out << " missing";
if (bh.bl.length() > 0) out << " firstbyte=" << (int)bh.bl[0];
if (bh.error) out << " error=" << bh.error;