stripe_off = offset % stripe_size;
while (length > 0) {
- string key;
- get_data_key(o->onode.nid, offset - stripe_off, &key);
bufferlist stripe;
- db->get(PREFIX_DATA, key, &stripe);
+ _do_read_stripe(o, offset - stripe_off, &stripe);
dout(30) << __func__ << " stripe " << offset - stripe_off << " got "
<< stripe.length() << dendl;
unsigned swant = MIN(stripe_size - stripe_off, length);
<< dendl;
assert((*p)->flush_txns.count(txc));
(*p)->flush_txns.erase(txc);
- if ((*p)->flush_txns.empty())
+ if ((*p)->flush_txns.empty()) {
(*p)->flush_cond.Signal();
+ (*p)->clear_pending_stripes();
+ }
}
// clear out refs
*_dout << dendl;
}
+void KStore::_do_read_stripe(OnodeRef o, uint64_t offset, bufferlist *pbl)
+{
+ map<uint64_t,bufferlist>::iterator p = o->pending_stripes.find(offset);
+ if (p == o->pending_stripes.end()) {
+ string key;
+ get_data_key(o->onode.nid, offset, &key);
+ db->get(PREFIX_DATA, key, pbl);
+ o->pending_stripes[offset] = *pbl;
+ } else {
+ *pbl = p->second;
+ }
+}
+
+void KStore::_do_write_stripe(TransContext *txc, OnodeRef o,
+ uint64_t offset, bufferlist& bl)
+{
+ o->pending_stripes[offset] = bl;
+ string key;
+ get_data_key(o->onode.nid, offset, &key);
+ txc->t->set(PREFIX_DATA, key, bl);
+}
+
+void KStore::_do_remove_stripe(TransContext *txc, OnodeRef o, uint64_t offset)
+{
+ o->pending_stripes.erase(offset);
+ string key;
+ get_data_key(o->onode.nid, offset, &key);
+ txc->t->rmkey(PREFIX_DATA, key);
+}
+
int KStore::_do_write(TransContext *txc,
OnodeRef o,
uint64_t offset, uint64_t length,
if (offset_rem == 0 && end_rem == 0) {
bufferlist bl;
bl.substr_of(orig_bl, bl_off, stripe_size);
- string key;
- get_data_key(o->onode.nid, offset, &key);
dout(30) << __func__ << " full stripe " << offset << dendl;
- txc->t->set(PREFIX_DATA, key, bl);
+ _do_write_stripe(txc, o, offset, bl);
offset += stripe_size;
length -= stripe_size;
bl_off += stripe_size;
continue;
}
uint64_t stripe_off = offset - offset_rem;
- string key;
- get_data_key(o->onode.nid, stripe_off, &key);
bufferlist prev;
- db->get(PREFIX_DATA, key, &prev);
+ _do_read_stripe(o, stripe_off, &prev);
dout(20) << __func__ << " read previous stripe " << stripe_off
<< ", got " << prev.length() << dendl;
bufferlist bl;
dout(30) << " writing:\n";
bl.hexdump(*_dout);
*_dout << dendl;
- txc->t->set(PREFIX_DATA, key, bl);
+ _do_write_stripe(txc, o, stripe_off, bl);
offset += use;
length -= use;
}
uint64_t pos = offset;
uint64_t stripe_off = pos % stripe_size;
while (pos < offset + length) {
- string key;
- get_data_key(o->onode.nid, pos - stripe_off, &key);
if (stripe_off || end - pos < stripe_size) {
bufferlist stripe;
- db->get(PREFIX_DATA, key, &stripe);
+ _do_read_stripe(o, pos - stripe_off, &stripe);
dout(30) << __func__ << " stripe " << pos - stripe_off << " got "
<< stripe.length() << dendl;
bufferlist bl;
bl.claim_append(t);
}
}
- txc->t->set(PREFIX_DATA, key, bl);
+ _do_write_stripe(txc, o, pos - stripe_off, bl);
pos += stripe_size - stripe_off;
stripe_off = 0;
} else {
dout(20) << __func__ << " rm stripe " << pos << dendl;
- txc->t->rmkey(PREFIX_DATA, key);
+ _do_remove_stripe(txc, o, pos - stripe_off);
pos += stripe_size;
}
}
uint64_t pos = offset;
uint64_t stripe_off = pos % stripe_size;
while (pos < o->onode.size) {
- string key;
- get_data_key(o->onode.nid, pos - stripe_off, &key);
if (stripe_off) {
bufferlist stripe;
- db->get(PREFIX_DATA, key, &stripe);
+ _do_read_stripe(o, pos - stripe_off, &stripe);
dout(30) << __func__ << " stripe " << pos - stripe_off << " got "
<< stripe.length() << dendl;
bufferlist t;
t.substr_of(stripe, 0, MIN(stripe_off, stripe.length()));
- txc->t->set(PREFIX_DATA, key, t);
+ _do_write_stripe(txc, o, pos - stripe_off, t);
dout(20) << __func__ << " truncated stripe " << pos - stripe_off
<< " to " << t.length() << dendl;
pos += stripe_size - stripe_off;
stripe_off = 0;
} else {
dout(20) << __func__ << " rm stripe " << pos << dendl;
- txc->t->rmkey(PREFIX_DATA, key);
+ _do_remove_stripe(txc, o, pos - stripe_off);
pos += stripe_size;
}
}