}
*/
+void ObjectCache::touch_bottom(block_t bstart, block_t blast)
+{
+ for (map<block_t, BufferHead*>::iterator p = data.lower_bound(bstart);
+ p != data.end();
+ ++p) {
+ BufferHead *bh = p->second;
+
+ // don't trim unless it's entirely in our range
+ if (bh->start() < bstart) continue;
+ if (bh->end() > blast) break;
+
+ dout(12) << "moving " << *bh << " to bottom of lru" << endl;
+ bc->touch_bottom(bh); // move to bottom of lru list
+ }
+}
+
+
void ObjectCache::truncate(block_t blocks, version_t super_epoch)
{
dout(7) << "truncate " << object_id
interval_set<block_t>& alloc,
map<block_t, BufferHead*>& hits,
version_t super_epoch); // can write to these.
+ void touch_bottom(block_t bstart, block_t blast);
BufferHead *split(BufferHead *bh, block_t off);
} else
lru_rest.lru_touch(bh);
}
+ void touch_bottom(BufferHead *bh) {
+ if (bh->is_dirty()) {
+ lru_dirty.lru_bottouch(bh);
+ } else
+ lru_rest.lru_bottouch(bh);
+ }
void remove_bh(BufferHead *bh) {
bh->get_oc()->remove_bh(bh);
stat_sub(bh);
*/
}
+void Ebofs::trim_from_cache(object_t oid, off_t off, size_t len)
+{
+ ebofs_lock.Lock();
+ _trim_from_cache(oid, off, len);
+ ebofs_lock.Unlock();
+}
+
+void Ebofs::_trim_from_cache(object_t oid, off_t off, size_t len)
+{
+ Onode *on = 0;
+ if (onode_map.count(oid) == 0) {
+ dout(7) << "_trim_from_cache " << oid << " " << off << "~" << len << " ... onode not in cache " << endl;
+ return;
+ }
+
+ if (!on->have_oc())
+ return; // nothing is cached.
+
+ // map to blocks
+ block_t bstart = off / EBOFS_BLOCK_SIZE;
+ block_t blast = (len+off-1) / EBOFS_BLOCK_SIZE;
+
+ ObjectCache *oc = on->get_oc(&bc);
+ oc->touch_bottom(bstart, blast);
+
+ return;
+}
+
+
int Ebofs::read(object_t oid,
off_t off, size_t len,
bufferlist& bl)
}
break;
+ case Transaction::OP_TRIMCACHE:
+ {
+ object_t oid = t.oids.front(); t.oids.pop_front();
+ off_t offset = t.offsets.front(); t.offsets.pop_front();
+ size_t len = t.lengths.front(); t.lengths.pop_front();
+ _trim_from_cache(oid, offset, len);
+ }
+ break;
+
case Transaction::OP_TRUNCATE:
{
object_t oid = t.oids.front(); t.oids.pop_front();
int is_cached(object_t oid, off_t off, size_t len);
int write(object_t oid, off_t off, size_t len, bufferlist& bl, Context *onsafe);
+ void trim_from_cache(object_t oid, off_t off, size_t len);
int truncate(object_t oid, off_t size, Context *onsafe=0);
int truncate_front(object_t oid, off_t size, Context *onsafe=0);
int remove(object_t oid, Context *onsafe=0);
bool _write_will_block();
int _write(object_t oid, off_t off, size_t len, bufferlist& bl);
+ void _trim_from_cache(object_t oid, off_t off, size_t len);
int _truncate(object_t oid, off_t size);
int _truncate_front(object_t oid, off_t size);
int _remove(object_t oid);
static const int OP_RMATTR = 16; // oid, attrname
static const int OP_CLONE = 17; // oid, newoid
+ static const int OP_TRIMCACHE = 18; // oid, offset, len
+
static const int OP_MKCOLL = 20; // cid
static const int OP_RMCOLL = 21; // cid
static const int OP_COLL_ADD = 22; // cid, oid
lengths.push_back(len);
bls.push_back(bl);
}
+ void trim_from_cache(object_t oid, off_t off, size_t len) {
+ int op = OP_TRIMCACHE;
+ ops.push_back(op);
+ oids.push_back(oid);
+ offsets.push_back(off);
+ lengths.push_back(len);
+ }
void truncate(object_t oid, off_t off) {
int op = OP_TRUNCATE;
ops.push_back(op);
}
break;
+ case Transaction::OP_TRIMCACHE:
+ {
+ object_t oid = t.oids.front(); t.oids.pop_front();
+ off_t offset = t.offsets.front(); t.offsets.pop_front();
+ size_t len = t.lengths.front(); t.lengths.pop_front();
+ trim_from_cache(oid, offset, len);
+ }
+ break;
+
case Transaction::OP_TRUNCATE:
{
object_t oid = t.oids.front(); t.oids.pop_front();
off_t offset, size_t len,
bufferlist& bl,
Context *onsafe) = 0;//{ return -1; }
+ virtual void trim_from_cache(object_t oid,
+ off_t offset, size_t len) { }
virtual int setattr(object_t oid, const char *name,
const void *value, size_t size,