struct lpurge_object {
struct lipe_list_head lo_list;
struct lu_fid lo_fid;
- /* Used space in bytes */
- __u32 lo_blocks;
+ __u32 lo_used_kb;
__u32 lo_mirror_id;
/* Last use time */
time_t lo_last_utime;
time_t ls_max_utime;
unsigned long ls_age;
unsigned long ls_found;
- /* Used space in bytes */
- unsigned long ls_space;
+ unsigned long ls_used_kb;
unsigned long ls_stored; /* FIDs stored */
unsigned int ls_scan;
struct lipe_list_head ls_obj_list;
pthread_mutex_t ls_mutex;
/* stats for objects we can't release */
unsigned long ls_nomirror_objs; /* no replicated objects */
- unsigned long ls_nomirror_space;
+ unsigned long ls_nomirror_used_kb;
unsigned long ls_nopfid_objs; /* no PFID, can't find parent */
- unsigned long ls_nopfid_space;
+ unsigned long ls_nopfid_used_kb;
unsigned long ls_notfirst_objs; /* not a first stripe */
- unsigned long ls_notfirst_space;
+ unsigned long ls_notfirst_used_kb;
};
#define LPURGE_HIST_MAX 16
#define LPURGE_FLIST_SIZE (1024 * 1024)
+static inline unsigned long long loa_used_kb(const struct lipe_object_attrs *loa)
+{
+ /* XXX XXX XXX loa_blocks is in units of bytes. */
+ return loa->loa_blocks >> 10;
+}
+
static void sig_handler(int signal)
{
psignal(signal, "exiting");
lpurge_hist[i].ls_min_utime = ~0UL;
lpurge_hist[i].ls_max_utime = 0;
lpurge_hist[i].ls_found = 0;
- lpurge_hist[i].ls_space = 0;
+ lpurge_hist[i].ls_used_kb = 0;
lpurge_hist[i].ls_stored = 0;
LIPE_INIT_LIST_HEAD(&lpurge_hist[i].ls_obj_list);
age = age << 1;
for (i = 0; i < LPURGE_HIST_MAX; i++) {
lpurge_hist[i].ls_found = 0;
- lpurge_hist[i].ls_space = 0;
+ lpurge_hist[i].ls_used_kb = 0;
lpurge_hist[i].ls_stored = 0;
lpurge_hist[i].ls_scan = 1;
lpurge_hist[i].ls_min_utime = ~0UL;
lpurge_hist[i].ls_max_utime = 0;
lpurge_hist[i].ls_nopfid_objs = 0;
- lpurge_hist[i].ls_nopfid_space = 0;
+ lpurge_hist[i].ls_nopfid_used_kb = 0;
lpurge_hist[i].ls_nomirror_objs = 0;
- lpurge_hist[i].ls_nomirror_space = 0;
+ lpurge_hist[i].ls_nomirror_used_kb = 0;
lpurge_hist[i].ls_notfirst_objs = 0;
- lpurge_hist[i].ls_notfirst_space = 0;
+ lpurge_hist[i].ls_notfirst_used_kb = 0;
lipe_list_for_each_entry_safe(s, t, &lpurge_hist[i].ls_obj_list,
lo_list) {
lipe_list_del(&s->lo_list);
pthread_mutex_lock(&ls_1->ls_mutex);
ls_1->ls_found = 0;
- ls_1->ls_space = 0;
+ ls_1->ls_used_kb = 0;
ls_1->ls_stored = 0;
ls_1->ls_max_utime = 0;
ls_1->ls_min_utime = ~0UL;
&ls_1->ls_obj_list);
ls_1->ls_stored = ls_2->ls_stored;
ls_1->ls_found = ls_2->ls_found;
- ls_1->ls_space = ls_2->ls_space;
+ ls_1->ls_used_kb = ls_2->ls_used_kb;
ls_1->ls_age = ls_2->ls_age;
ls_1->ls_max_utime = ls_2->ls_max_utime;
ls_1->ls_min_utime = ls_2->ls_min_utime;
pthread_mutex_lock(&lpurge_hist[index].ls_mutex);
lpurge_hist[index].ls_stored = 0;
lpurge_hist[index].ls_found = 0;
- lpurge_hist[index].ls_space = 0;
+ lpurge_hist[index].ls_used_kb = 0;
lpurge_hist[index].ls_min_utime = ~0UL;
lpurge_hist[index].ls_max_utime = 0;
lpurge_hist[index].ls_age = lpurge_hist[index + 1].ls_age;
if ((attrs->loa_attr_bits & LIPE_OBJECT_ATTR_LOVEA) == 0) {
ls->ls_nomirror_objs++;
- ls->ls_nomirror_space += attrs->loa_blocks >> 10;
+ ls->ls_nomirror_used_kb += loa_used_kb(attrs);
return 0;
}
if (comp_v1->lcm_magic != LOV_USER_MAGIC_COMP_V1 ||
comp_v1->lcm_mirror_count == 0) {
ls->ls_nomirror_objs++;
- ls->ls_nomirror_space += attrs->loa_blocks >> 10;
+ ls->ls_nomirror_used_kb += loa_used_kb(attrs);
return 0;
}
}
ls->ls_nomirror_objs++;
- ls->ls_nomirror_space += attrs->loa_blocks >> 10;
+ ls->ls_nomirror_used_kb += loa_used_kb(attrs);
return 0;
}
{
if ((attrs->loa_attr_bits & LIPE_OBJECT_ATTR_FILTER_FID) == 0) {
ls->ls_nopfid_objs++;
- ls->ls_nopfid_space += attrs->loa_blocks >> 10;
+ ls->ls_nopfid_used_kb += loa_used_kb(attrs);
return 0;
}
*/
if (attrs->loa_filter_fid.ff_parent.f_ver != 0) {
ls->ls_notfirst_objs++;
- ls->ls_notfirst_space += attrs->loa_blocks >> 10;
+ ls->ls_notfirst_used_kb += loa_used_kb(attrs);
return 0;
}
if (mirror_id_of(attrs->loa_filter_fid.ff_layout.ol_comp_id)
== 0) {
ls->ls_nomirror_objs++;
- ls->ls_nomirror_space += attrs->loa_blocks >> 10;
+ ls->ls_nomirror_used_kb += loa_used_kb(attrs);
return 0;
}
}
if (!rc)
goto out_ls_mutex;
- LX_DEBUG("found under "DFID": size %ld block %ld age %ld slot %d\n",
+ LX_DEBUG("found under "DFID": size_kb %llu, used_kb %llu, age %ld, slot %d\n",
PFID(&attrs->loa_filter_fid.ff_parent),
- (unsigned long)attrs->loa_size,
- (unsigned long)attrs->loa_blocks >> 10, age, index);
+ (unsigned long long)(attrs->loa_size >> 10),
+ loa_used_kb(attrs),
+ age,
+ index);
ls->ls_found++;
- ls->ls_space += attrs->loa_blocks >> 10;
+ ls->ls_used_kb += loa_used_kb(attrs);
lpurge_scanned_since++;
/*
goto out_ls_mutex;
} else {
ls->ls_found--;
- ls->ls_space -= attrs->loa_blocks >> 10;
+ ls->ls_used_kb -= loa_used_kb(attrs);
pthread_mutex_unlock(&ls->ls_mutex);
index--;
ls = lpurge_hist + index;
pthread_mutex_lock(&ls->ls_mutex);
ls->ls_found++;
- ls->ls_space += attrs->loa_blocks >> 10;
+ ls->ls_used_kb += loa_used_kb(attrs);
}
}
lo = xcalloc(1, sizeof(*lo));
lo->lo_fid = attrs->loa_filter_fid.ff_parent;
- lo->lo_blocks = attrs->loa_blocks >> 10;
+ lo->lo_used_kb = loa_used_kb(attrs);
lo->lo_last_utime = last_used;
if (attrs->loa_filter_fid_size >= sizeof(struct filter_fid)) {
__u32 id;
}
#endif
-static void lpurge_purge_slot(struct lpurge_slot *ls, long long target)
+static void lpurge_purge_slot(struct lpurge_slot *ls, long long target_kb)
{
struct lpurge_object *lo;
- unsigned long long total, prev_used_kb, used_kb;
+ unsigned long long queued_kb, prev_used_kb, used_kb;
long long purged_kb;
int i, rc;
- /* try to remove some replicas */
again:
- LX_DEBUG("release upto %llu (expect %lu in %lu)\n",
- target, ls->ls_space, ls->ls_found);
- total = 0;
+ LX_DEBUG("releasing upto %llu KB: expect %lu KB from %lu objects\n",
+ target_kb, ls->ls_used_kb, ls->ls_found);
+ queued_kb = 0;
assert(!lipe_list_empty(&ls->ls_obj_list));
lo = lipe_list_entry(ls->ls_obj_list.next, struct lpurge_object,
lo_list);
- /* how many blocks we expect to free */
- total += lo->lo_blocks;
- ls->ls_space -= lo->lo_blocks;
+ queued_kb += lo->lo_used_kb;
+ ls->ls_used_kb -= lo->lo_used_kb;
ls->ls_found--;
ls->ls_stored--;
stats.s_queued++;
/* if current collection of objects may free target space, then stop */
- if (total >= target)
+ if (queued_kb >= target_kb)
break;
}
/* estimate how much space has been released
*/
- rc = lpurge_get_used_kb(&prev_used_kb);
+ rc = lpurge_get_used_kb(&used_kb);
if (rc)
return;
- /* FIXME Clarify units of total. */
- LX_DEBUG("spawn, expect %llu back\n", total);
- LX_DEBUG_D(target);
- LX_DEBUG_U(total);
+ LX_DEBUG_U(queued_kb);
+ LX_DEBUG_D(target_kb);
+ LX_DEBUG_U(used_kb);
+ prev_used_kb = used_kb;
/* Wait for purge threads to complete all submitted work. */
pthread_mutex_lock(&lpurge_work_lock);
return;
purged_kb = prev_used_kb - used_kb;
- LX_DEBUG_U(prev_used_kb);
- LX_DEBUG_U(used_kb);
LX_DEBUG_D(purged_kb);
- /* XXX purged_kb is signed. */
- if (purged_kb > 0 && purged_kb >= total)
+ if (purged_kb > 0 && purged_kb >= queued_kb)
break;
}
if (purged_kb > 0)
- target -= purged_kb;
+ target_kb -= purged_kb;
- if (target <= 0 || used_kb <= lpurge_min_used_kb) {
+ if (target_kb <= 0 || used_kb <= lpurge_min_used_kb) {
/* got enough space back, relax */
LX_DEBUG("relax\n");
return;
for (i = 0; i < LPURGE_HIST_MAX; i++) {
if (&lpurge_hist[i] == ls) {
lpurge_hist[i].ls_found = 0;
- lpurge_hist[i].ls_space = 0;
+ lpurge_hist[i].ls_used_kb = 0;
lpurge_hist[i].ls_stored = 0;
lpurge_hist[i].ls_scan = 1;
} else {
*/
}
-static void lpurge_free_space(void)
+static void lpurge_purge(void)
{
unsigned long long used_kb;
int i, rc;
for (i = LPURGE_HIST_MAX - 1; i >= 0; i--) {
struct lpurge_slot *ls = lpurge_hist + i;
- if (ls->ls_found == 0/* || ls->ls_space == 0*/)
+ if (ls->ls_found == 0/* || ls->ls_used_kb == 0*/)
continue;
rc = lpurge_get_used_kb(&used_kb);
for (i = 0; i < LPURGE_HIST_MAX; i++) {
if (!lipe_list_empty(&lpurge_hist[i].ls_obj_list)) {
LX_DEBUG("slot %d isnt empty: %lu in %lu\n",
- i, lpurge_hist[i].ls_space,
+ i, lpurge_hist[i].ls_used_kb,
lpurge_hist[i].ls_found);
return;
}
continue;
LX_DEBUG("%d (< %lu): %lu in %lu objects\n",
i, lpurge_hist[i].ls_age,
- lpurge_hist[i].ls_space,
+ lpurge_hist[i].ls_used_kb,
lpurge_hist[i].ls_found);
}
}
total_kb);
#define HIST_FMT \
- " hist%u: { age: %lu, found: %lu, space: %lu, stored: %lu, nomirror_cnt: %lu, nomirror_space: %lu, nopfid_cnt: %lu, nopfid_space: %lu, notfirst_cnt: %lu, notfirst_space: %lu }\n"
+ " hist%u: { age: %lu, found: %lu, space: %lu, stored: %lu, nomirror_cnt: %lu, nomirror_used_kb: %lu, nopfid_cnt: %lu, nopfid_used_kb: %lu, notfirst_cnt: %lu, notfirst_used_kb: %lu }\n"
fprintf(f, "hlists:\n");
for (i = LPURGE_HIST_MAX - 1; i >= 0; i--) {
continue;
fprintf(f, HIST_FMT, i, ls->ls_age, ls->ls_found,
- ls->ls_space, ls->ls_stored,
- ls->ls_nomirror_objs,ls->ls_nomirror_space,
- ls->ls_nopfid_objs, ls->ls_nopfid_space,
- ls->ls_notfirst_objs, ls->ls_notfirst_space);
+ ls->ls_used_kb, ls->ls_stored,
+ ls->ls_nomirror_objs, ls->ls_nomirror_used_kb,
+ ls->ls_nopfid_objs, ls->ls_nopfid_used_kb,
+ ls->ls_notfirst_objs, ls->ls_notfirst_used_kb);
}
fflush(f);
/*
* dump summary first
- * {Summary: {"min_utime": 12345, "max_utime": 345669, "total_found": 100000, "total_stored": 100000, "total_space": 456780000}}
+ * {Summary: {"min_utime": 12345, "max_utime": 345669, "total_found": 100000, "total_stored": 100000, "total_used_kb": 456780000}}
*/
for (i = LPURGE_HIST_MAX - 1; i >= 0; i--) {
struct lpurge_slot *ls = lpurge_hist + i;
if (min_utime > ls->ls_min_utime)
min_utime = ls->ls_min_utime;
found_sum += ls->ls_found;
- space_sum += ls->ls_space;
+ space_sum += ls->ls_used_kb;
stored_sum += ls->ls_stored;
}
json_object_object_add(slot_stats, "stored",
json_object_new_int64(ls->ls_stored));
json_object_object_add(slot_stats, "space",
- json_object_new_int64(ls->ls_space));
+ json_object_new_int64(ls->ls_used_kb));
snprintf(buff, sizeof(buff), "slot_%d", i);
json_object_object_add(obj_slot, buff, slot_stats);
lpurge_scan_rate = opt.o_scan_rate;
lpurge_scan();
- lpurge_free_space();
+ lpurge_purge();
/* device size can change runtime.. */
lpurge_configure_thresholds();