client_flush_set_callback, // all commit callback
(void*)this,
cct->_conf->client_oc_size,
+ cct->_conf->client_oc_max_objects,
cct->_conf->client_oc_max_dirty,
cct->_conf->client_oc_target_dirty,
cct->_conf->client_oc_max_dirty_age);
OPTION(client_oc_max_dirty, OPT_INT, 1024*1024* 100) // MB * n (dirty OR tx.. bigish)
OPTION(client_oc_target_dirty, OPT_INT, 1024*1024* 8) // target dirty (keep this smallish)
OPTION(client_oc_max_dirty_age, OPT_DOUBLE, 5.0) // max age in cache before writeback
+OPTION(client_oc_max_objects, OPT_INT, 1000) // max objects in cache
// note: the max amount of "in flight" dirty data is roughly (max - target)
OPTION(fuse_use_invalidate_cb, OPT_BOOL, false) // use fuse 2.8+ invalidate callback to keep page cache consistent
OPTION(fuse_big_writes, OPT_BOOL, true)
object_cacher = new ObjectCacher(cct, pname, *writeback_handler, cache_lock,
NULL, NULL,
cct->_conf->rbd_cache_size,
+ cct->_conf->rbd_cache_size / (4 << 20) * 2 + 10,
cct->_conf->rbd_cache_max_dirty,
cct->_conf->rbd_cache_target_dirty,
cct->_conf->rbd_cache_max_dirty_age);
ObjectCacher::ObjectCacher(CephContext *cct_, string name, WritebackHandler& wb, Mutex& l,
flush_set_callback_t flush_callback,
void *flush_callback_arg,
- uint64_t max_size, uint64_t max_dirty, uint64_t target_dirty, double max_dirty_age)
+ uint64_t max_bytes, uint64_t max_objects,
+ uint64_t max_dirty, uint64_t target_dirty, double max_dirty_age)
: perfcounter(NULL),
cct(cct_), writeback_handler(wb), name(name), lock(l),
- max_dirty(max_dirty), target_dirty(target_dirty), max_size(max_size),
+ max_dirty(max_dirty), target_dirty(target_dirty),
+ 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),
}
-void ObjectCacher::trim(loff_t max_bytes, loff_t max_objects)
+void ObjectCacher::trim(loff_t max_bytes, loff_t max_ob)
{
- if (max < 0)
- max = max_size;
+ if (max_bytes < 0)
+ max_bytes = max_size;
+ if (max_ob < 0)
+ max_ob = max_objects;
ldout(cct, 10) << "trim start: bytes: max " << max_bytes << " clean " << get_stat_clean()
- << ", objects: max " << max_objects << " current " << ob_lru.get_lru_size()
+ << ", objects: max " << max_ob << " current " << ob_lru.lru_get_size()
<< dendl;
while (get_stat_clean() > max_bytes) {
BufferHead *bh = (BufferHead*) bh_lru_rest.lru_expire();
- if (!bh) break;
-
+ if (!bh)
+ break;
+
ldout(cct, 10) << "trim trimming " << *bh << dendl;
assert(bh->is_clean());
-
+
Object *ob = bh->ob;
bh_remove(ob, bh);
delete bh;
}
}
- while (ob_lru.lru_get_size() > max_objects) {
- // ...
+ while (ob_lru.lru_get_size() > max_ob) {
+ Object *ob = (Object*)ob_lru.lru_expire();
+ if (!ob)
+ break;
+
+ ldout(cct, 10) << "trim trimming " << *ob << dendl;
+ close_object(ob);
}
ldout(cct, 10) << "trim finish: max " << max_bytes << " clean " << get_stat_clean()
- << ", objects: max " << max_objects << " current " << ob_lru.get_lru_size()
+ << ", objects: max " << max_ob << " current " << ob_lru.lru_get_size()
<< dendl;
}
string name;
Mutex& lock;
- int64_t max_dirty, target_dirty, max_size;
+ int64_t max_dirty, target_dirty, max_size, max_objects;
utime_t max_dirty_age;
flush_set_callback_t flush_set_callback;
void bh_read(BufferHead *bh);
void bh_write(BufferHead *bh);
- void trim(loff_t max=-1);
+ void trim(loff_t max_bytes=-1, loff_t max_objects=-1);
void flush(loff_t amount=0);
/**
ObjectCacher(CephContext *cct_, string name, WritebackHandler& wb, Mutex& l,
flush_set_callback_t flush_callback,
void *flush_callback_arg,
- uint64_t max_size, uint64_t max_dirty, uint64_t target_dirty, double max_age);
+ uint64_t max_bytes, uint64_t max_objects,
+ uint64_t max_dirty, uint64_t target_dirty, double max_age);
~ObjectCacher();
void start() {
void set_max_dirty_age(double a) {
max_dirty_age.set_from_double(a);
}
+ void set_max_objects(int64_t v) {
+ max_objects = v;
+ }
+
// file functions